Compare commits

...

85 Commits

Author SHA1 Message Date
arifal
4cc698a623 fix handle disable button when upload business industries 2025-02-28 10:37:41 +07:00
arifal
544ad1db46 fix upload business and industry with chunk 2025-02-28 00:35:09 +07:00
arifal
30ca819aa1 fix color on maps 2025-02-27 20:14:37 +07:00
arifal
b0bab784d1 partial update add page laporan pimpinan and fix upload big data excel pdam 2025-02-27 19:23:06 +07:00
arifal
01fda22c89 partial update add loading on maps and add color for zone type maps 2025-02-26 23:52:48 +07:00
arifal
de300c2c32 fix dashboard style and resume bigdata 2025-02-26 21:52:23 +07:00
arifal
7f8a2e4936 Merge branch 'feature/dashboard-pbg' into dev 2025-02-25 11:34:08 +07:00
@jamaludinarifrohman6661
38948b6633 bug-fix: map tourisms 2025-02-25 11:32:39 +07:00
arifal
aa9943ba45 hot fix vite config js resources 2025-02-25 04:18:15 +00:00
arifal
9e55ea0dbb fix change api route data settings 2025-02-25 10:41:59 +07:00
arifal
93f0ac5ef7 Merge branch 'feature/dashboard-pbg' into fix/dashboard-resume 2025-02-25 10:23:41 +07:00
@jamaludinarifrohman6661
8bae33519f feature: sebaran lokasi project pariwisata 2025-02-24 21:47:24 +07:00
@jamaludinarifrohman6661
6865e353e6 feature: first check point 2025-02-24 20:03:36 +07:00
arifal
bb4ab5c769 add filter date for dashboard 2025-02-24 19:00:09 +07:00
arifal hidayat
e743b82087 add remove disabled if error on data settings 2025-02-23 07:11:14 +07:00
arifal hidayat
c3c7b8e3ec fix js roles and add back button on card header 2025-02-23 07:08:50 +07:00
arifal hidayat
d49035ce8d fix js menus and handle api menus 2025-02-23 06:42:13 +07:00
arifal hidayat
ffd9d3514c fix business industries and data settings front end 2025-02-22 16:08:59 +07:00
arifal
675477c734 fix service sync simbg upsert integrations 2025-02-21 18:49:42 +07:00
arifal
4350c466e3 add backup db from local 2025-02-21 18:18:45 +07:00
arifal
5ab407d672 change get value dashboard pimpinan from resume bigdata 2025-02-21 18:09:32 +07:00
arifal
2aaa487746 fix get total data from api 2025-02-21 14:49:09 +07:00
arifal
080582f7ab add new menu peta in dashboard 2025-02-21 11:12:35 +07:00
arifal
91475aeead Merge branch 'dev' into feat/load-map-from-kmz 2025-02-21 10:43:06 +07:00
arifal
a7afbd69fb fix conflict spatial-plannings jamal 2025-02-21 09:07:15 +07:00
arifal
1ff5587050 merge conflix spatial-plannings 2025-02-21 08:42:08 +07:00
arifal
9c8a1a3f3f add vite js customers 2025-02-21 00:49:29 +07:00
arifal
5c4be7635b partial update crud customer data 2025-02-21 00:46:33 +07:00
@jamaludinarifrohman6661
ba315b1dee Fix: upload bulk in column date, and fix template 2025-02-20 22:54:41 +07:00
@jamaludinarifrohman6661
33b7131c33 feature: crud spatial planning and fix search in tourism and umkm 2025-02-20 16:16:06 +07:00
arifal
7a56735099 done crud spatial plannings 2025-02-20 15:35:06 +07:00
@jamaludinarifrohman6661
dd331b4a08 create message error validation on advertisementrequest and tourismsrequest 2025-02-20 10:59:32 +07:00
@jamaludinarifrohman6661
dcd93d66e2 fix: change path download template and add template pariwisata 2025-02-20 10:36:56 +07:00
arifal
5d50d6d6cc fix height card 2025-02-19 15:34:28 +07:00
arifal
39717d184c partial update create google map from kmz file 2025-02-19 14:31:12 +07:00
arifal
54146c8c08 partial update spatial plannings crud 2025-02-19 12:08:18 +07:00
arifal
e8da7193ef fix crud users 2025-02-19 11:23:15 +07:00
arifal
006c008542 done dashboard-potential 2025-02-19 07:22:06 +07:00
root
39bb8e6d5f hot fix vite and create view 2025-02-18 23:49:48 +00:00
arifal
7994a62cea change name dashboard 2025-02-19 06:24:44 +07:00
arifal
3a09e2e68a Merge branch 'bug-fix/tourisms' into feat/dashboard-kekurangan-potensi 2025-02-19 06:17:16 +07:00
arifal
116dc1c8c7 add dashboard potential 2025-02-19 06:15:35 +07:00
@jamaludinarifrohman6661
f10bc153b4 fix: tourisms 2025-02-19 01:39:27 +07:00
@jamaludinarifrohman6661
06a3bb8c8b fix:pariwisata and report pariwisata 2025-02-19 01:07:20 +07:00
arifal
6c936d4c14 add more handle if zero devided 2025-02-18 03:40:20 +07:00
arifal
d4d0a485cd fix vite resources 2025-02-18 03:32:00 +07:00
arifal
864fb26471 add local db backup 2025-02-18 02:58:11 +07:00
arifal
fd97a34344 add vite resources 2025-02-18 02:50:34 +07:00
arifal
1dd971fb73 create update tourisms 2025-02-18 02:45:39 +07:00
arifal
aff31e08ef merge feature umkm 2025-02-18 00:46:51 +07:00
arifal
beac71d182 add business industry crud 2025-02-17 18:40:00 +07:00
arifal hidayat
154b7f40df add sync data setting 2025-02-17 01:52:49 +07:00
arifal
59e9431b2d fetch data from data setting and make seeder realisasi terbit, menunggu klik dpmptsp, proses dinas teknis 2025-02-14 18:28:14 +07:00
arifal
074edc607d add hardcode number for realisasi terbit, proses dinas teknis, menunggu klik dashboards 2025-02-14 17:04:49 +07:00
arifal
625d182d81 fix service google sheet, add uemail to profile, fix detail pbg view, backupdb local last migrate, create menu and role request 2025-02-14 16:22:34 +07:00
arifal
4d32d4a110 fix button and fix service sync simbg 2025-02-14 00:23:50 +07:00
arifal
ac2f37d549 add js builk create 2025-02-13 01:50:14 +07:00
arifal
a9afb47f08 change filter year on dashboard to dropdown 2025-02-13 01:17:22 +07:00
arifal
9efb6c346e fix conflict and add seeder vilages 2025-02-12 23:50:16 +07:00
arifal
6ba62da5ca merge with feat reklame 2025-02-12 22:24:23 +07:00
arifal
ba95c185de create filter and bigdata resume sync 2025-02-12 21:28:08 +07:00
arifal
b4b34b503e fix loading all pages 2025-02-12 01:53:40 +07:00
arifal
1a15bc03f8 create loading and handle from js create edit and delete roles 2025-02-11 23:40:31 +07:00
arifal
2bf4b8b327 create feat management role menu 2025-02-11 17:59:03 +07:00
arifal
cb90f69d1e create user role and menu, create seeder for first user and create crud role, menu and user 2025-02-11 02:35:53 +07:00
arifal
6307417ae3 add latest created import datasource and change icon 404 page 2025-02-07 18:31:52 +07:00
arifal
55dc0751d3 fix relation, fix migration, fix all route use token, fix service sync simbg, fix detail pbg 2025-02-07 16:03:52 +07:00
arifal
97ffd322a1 partial update add env for setting api url from env, partial update detail pbg, add tata ruang for dashboard pimpinan, fix service sync simbg add unique for prasarana table 2025-02-07 09:45:29 +07:00
Firman Herdiansyah
6fb59e58e9 Remove slash 2025-02-06 10:51:14 +07:00
Firman Herdiansyah
7e99d547c8 Update Config 2025-02-06 10:49:16 +07:00
Firman Herdiansyah
65f82c9bfd Update Vite Config 2025-02-06 10:42:41 +07:00
arifal
44ebc20d3c checkout 2025-02-06 09:03:02 +07:00
arifal
b60bbd4290 push with build 2025-02-06 08:40:19 +07:00
arifal
29b705b59c add local db 2025-02-06 07:59:35 +07:00
arifal
95ab8eff7f add alias vite config 2025-02-06 07:15:01 +07:00
arifal
bfc2f7f1f9 remove circle scss on component 2025-02-06 06:53:23 +07:00
Firman Herdiansyah
50f1757a64 Init First Release 2025-02-06 05:19:19 +07:00
arifal
d54edb7783 update 2025-06-02 2025-02-06 04:55:30 +07:00
Firman Herdiansyah
3309664bae Update Dashboard 2025-02-06 04:53:20 +07:00
arifal
4eac6ab83d Merge remote-tracking branch 'origin/dev' into feat/data-settings 2025-02-05 13:40:13 +07:00
arifal
604e0d8479 partial updates create service google sheet 2025-02-05 13:38:21 +07:00
Firman Herdiansyah
99e99fa2e6 Update Dashboard Layout 2025-02-05 13:36:33 +07:00
arifal
ff324014f6 partial update create crud pbg 2025-02-05 02:40:14 +07:00
arifal
7d06e12de8 create crud data settings 2025-02-04 21:49:10 +07:00
Firman Herdiansyah
f38d518f96 Init Dev 2025-02-04 19:53:59 +07:00
253 changed files with 112700 additions and 5891 deletions

View File

@@ -4,6 +4,7 @@ APP_KEY=
APP_DEBUG=true APP_DEBUG=true
APP_TIMEZONE=UTC APP_TIMEZONE=UTC
APP_URL=http://localhost APP_URL=http://localhost
API_URL=http://localhost:8000
APP_LOCALE=en APP_LOCALE=en
APP_FALLBACK_LOCALE=en APP_FALLBACK_LOCALE=en
@@ -65,6 +66,5 @@ AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}" VITE_APP_NAME="${APP_NAME}"
SIMBG_HOST="xxxxxx" API_KEY_GOOGLE="xxxxx"
SIMBG_EMAIL="xxxxxx" SPREAD_SHEET_ID="xxxxx"
SIMBG_PASSWORD="xxxxx"

View File

@@ -1,66 +1,37 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p> # Usage icon
<p align="center"> search or pick icon in <a href="https://icon-sets.iconify.design/mingcute/?keyword=mingcute">here</a>
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel # Set up queue for running automatically
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: - Install Supervisor
- [Simple, fast routing engine](https://laravel.com/docs/routing). ```
- [Powerful dependency injection container](https://laravel.com/docs/container). sudo apt update && sudo apt install supervisor -y
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. ```
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications. - Create Supervisor Config
## Learning Laravel ```
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. [program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path-to-your-project/artisan queue:work --tries=3 --timeout=600
autostart=true
autorestart=true
numprocs=1
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel-worker.log
```
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
## Laravel Sponsors sudo supervisorctl update
sudo supervisorctl start laravel-worker
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). sudo supervisorctl restart laravel-worker
sudo supervisorctl status
### Premium Partners ```
- **[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)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
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).
## Security Vulnerabilities
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.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

View File

@@ -2,7 +2,7 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use App\ServiceSIMBG; use App\Services\ServiceSIMBG;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use \Illuminate\Support\Facades\Log; use \Illuminate\Support\Facades\Log;
@@ -25,10 +25,16 @@ class ExecuteScraping extends Command
/** /**
* Execute the console command. * Execute the console command.
*/ */
private $service_simbg;
public function __construct(ServiceSIMBG $service_simbg){
$this->service_simbg = $service_simbg;
parent::__construct();
}
public function handle() public function handle()
{ {
Log::info("running scheduler daily scraping"); Log::info("running scheduler daily scraping");
$service = new ServiceSIMBG(); $this->service_simbg->syncTaskList();
$service->syncTaskList();
} }
} }

View File

@@ -199,7 +199,7 @@ class AdvertisementController extends Controller
public function downloadExcelAdvertisement() public function downloadExcelAdvertisement()
{ {
$filePath = storage_path('app/public/templateFile/template_reklame.xlsx'); $filePath = public_path('templates/template_reklame.xlsx');
// Cek apakah file ada // Cek apakah file ada
if (!file_exists($filePath)) { if (!file_exists($filePath)) {

View File

@@ -0,0 +1,259 @@
<?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 filterByDate is "latest" or empty, get the most recent record
if (!$filterDate || $filterDate === "latest") {
$big_data_resume = BigdataResume::latest()->first();
} else {
// Filter by specific date
$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']);
}
$target_pad = floatval(optional($data_settings->where('key', 'TARGET_PAD')->first())->value);
$realisasi_terbit_pbg_sum = floatval(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_SUM')->first())->value);
$realisasi_terbit_pbg_count = floatval(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_COUNT')->first())->value);
$menuggu_klik_dpmptsp_sum = floatval(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_SUM')->first())->value);
$menuggu_klik_dpmptsp_count = floatval(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_COUNT')->first())->value);
$proses_dinas_teknis_sum = floatval(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_SUM')->first())->value);
$proses_dinas_teknis_count = floatval(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_COUNT')->first())->value);
$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 && $menuggu_klik_dpmptsp_sum > 0
? round(($menuggu_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' => $menuggu_klik_dpmptsp_sum,
'count' => $menuggu_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('name', 'LIKE', '%'.$request->input('search').'%');
}
$query = $query->paginate(15);
return BigdataResumeResource::collection($query)->response()->getData(true);
}catch(\Exception $e){
Log::error($e->getMessage());
return response()->json(['message' => 'Error when fetching data'], 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)
{
//
}
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);
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\BusinessIndustryRequest;
use App\Imports\BusinessIndustriesImport;
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
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = BusinessOrIndustry::query()->orderBy('id', 'desc');
if ($request->has("search") && !empty($request->get("search"))) {
$search = $request->get("search");
info($request); // Debugging log
$query->where(function ($q) use ($search) {
$q->where("nop", "LIKE", "%{$search}%")
->orWhere("nama_kecamatan", "LIKE", "%{$search}%")
->orWhere("nama_kelurahan", "LIKE", "%{$search}%");
});
}
return response()->json($query->paginate());
}
/**
* 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(BusinessIndustryRequest $request, string $id)
{
try{
$data = BusinessOrIndustry::findOrFail($id);
$data->update($request->validated());
return response()->json(['message' => 'Data updated successfully.'], 200);
}catch(\Exception $e){
\Log::error($e->getMessage());
return response()->json(['message' => 'Failed to update data'],500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
$data = BusinessOrIndustry::findOrFail($id);
$data->delete();
return response()->json(['message' => 'Data deleted successfully.'], 200);
}catch(\Exception $e){
\Log::error($e->getMessage());
return response()->json(['message' => 'Failed to delete data'],500);
}
}
public function upload(ExcelUploadRequest $request){
try {
if(!$request->hasFile('file')){
return response()->json([
'error' => 'No file provided'
], 400);
}
$file = $request->file('file');
Excel::import(new BusinessIndustriesImport, $file);
// Jika sukses, kembalikan respons sukses
return response()->json([
'message' => 'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
// Jika ada error, kembalikan error response
return response()->json([
'message' => 'Error during file import.',
'error' => $e->getMessage()
], 500);
}
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\CustomersRequest;
use App\Http\Requests\ExcelUploadRequest;
use App\Http\Resources\CustomersResource;
use App\Imports\CustomersImport;
use App\Models\Customer;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class CustomersController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$query = Customer::query()->orderBy('id', 'desc');
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_pelayanan', 'LIKE', '%'.$request->get('search').'%');
}
return CustomersResource::collection($query->paginate());
}
/**
* Store a newly created resource in storage.
*/
public function store(CustomersRequest $request)
{
try{
$customer = Customer::create($request->validated());
return response()->json(['message' => 'Successfully created', new CustomersResource($customer)]);
}catch(\Exception $e){
return response()->json([
'message' => 'Failed to create customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
try{
$customer = Customer::find($id);
if($customer){
return new CustomersResource($customer);
} else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e){
return response()->json([
'message' => 'Failed to retrieve customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Update the specified resource in storage.
*/
public function update(CustomersRequest $request, string $id)
{
try{
$customer = Customer::find($id);
if($customer){
$customer->update($request->validated());
return response()->json(['message' => 'Successfully updated', new CustomersResource($customer)]);
} else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e) {
return response()->json([
'message' => 'Failed to update customer',
'error' => $e->getMessage()
], 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
$customer = Customer::find($id);
if($customer){
$customer->delete();
return response()->json(['message' => 'Successfully deleted']);
}else {
return response()->json(['message' => 'Customer not found'], 404);
}
}catch(\Exception $e) {
return response()->json([
'message' => 'Failed to delete customer',
'error' => $e->getMessage()
], 500);
}
}
public function upload(ExcelUploadRequest $request){
try{
if(!$request->hasFile('file')){
return response()->json([
'error' => 'No file provided'
], 400);
}
$file = $request->file('file');
Excel::import(new CustomersImport, $file);
return response()->json([
'message' => 'File uploaded successfully',
]);
}catch(\Exception $e){
\Log::info($e->getMessage());
return response()->json([
'error' => 'Failed to upload file',
'message' => $e->getMessage()
], 500);
}
}
}

View File

@@ -11,63 +11,162 @@ class DashboardController extends Controller
{ {
use GlobalApiResponse; use GlobalApiResponse;
public function businnessDocument(Request $request){ public function businnessDocument(Request $request)
$businessData = DB::table('pbg_task') {
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid') $request->validate([
->select( "year" => "required|integer"
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'), ]);
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution')
) $current_year = $request->get('year');
->where(function ($query) {
$query->where("pbg_task.function_type", "LIKE", "sebagai tempat usaha%"); $startOfYear = "$current_year-01-01 00:00:00";
}) $endOfYear = "$current_year-12-31 23:59:59";
->first(); $query = once(function () use ($startOfYear, $endOfYear) {
$taskCount = $businessData->task_count; return DB::table('pbg_task AS pt')
$taskTotal = $businessData->total_retribution; ->leftJoin('pbg_task_google_sheet AS ptgs', 'pt.registration_number', '=', 'ptgs.no_registrasi')
$result = [ ->leftJoin('pbg_task_retributions AS ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
->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();
});
$taskCount = $query->total_data ?? 0;
$taskTotal = $query->total_retribution ?? 0;
return $this->resSuccess([
"count" => $taskCount, "count" => $taskCount,
"series" => [$taskCount],
"total" => $taskTotal "total" => $taskTotal
]; ]);
return $this->resSuccess($result);
} }
public function nonBusinnessDocument(Request $request){ public function nonBusinnessDocument(Request $request){
$businessData = DB::table('pbg_task') $request->validate([
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid') "year" => "required|integer"
->select( ]);
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'),
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution') $current_year = $request->get('year');
)
$startOfYear = "$current_year-01-01 00:00:00";
$endOfYear = "$current_year-12-31 23:59:59";
$query = once( function () use ($startOfYear, $endOfYear) {
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
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
->where(function ($query) { ->where(function ($query) {
$query->where("pbg_task.function_type", "NOT LIKE", "sebagai tempat usaha%") $query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
->orWhereNull("pbg_task.function_type"); ->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
}) })
->where(function ($query) {
$query->whereRaw('LOWER(TRIM(pt.function_type)) != ?', [strtolower(trim('Sebagai Tempat Usaha'))])
->orWhereNull('pt.function_type'); // Include NULL values
})
->selectRaw('COUNT(pt.id) AS total_data,
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
->first(); ->first();
$taskCount = $businessData->task_count; });
$taskTotal = $businessData->total_retribution; $taskCount = $query->total_data ?? 0;
$result = [ $taskTotal = $query->total_retribution ?? 0;
return $this->resSuccess([
"count" => $taskCount, "count" => $taskCount,
"series" => [$taskCount],
"total" => $taskTotal "total" => $taskTotal
]; ]);
return $this->resSuccess($result);
} }
public function allTaskDocuments(){ public function allTaskDocuments(Request $request){
$query = DB::table('pbg_task') $request->validate([
->leftJoin('pbg_task_retributions', 'pbg_task.uuid', '=', 'pbg_task_retributions.pbg_task_uid') "year" => "required|integer"
]);
$current_year = $request->get('year');
$startOfYear = "$current_year-01-01 00:00:00";
$endOfYear = "$current_year-12-31 23:59:59";
$query = once( function () use ($startOfYear, $endOfYear) {
return DB::table('pbg_task as pt')
->leftJoin('pbg_task_retributions as ptr', 'pt.uuid', '=', 'ptr.pbg_task_uid')
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
->select( ->select(
DB::raw('COUNT(DISTINCT pbg_task.id) as task_count'), DB::raw('COUNT(DISTINCT pt.id) as task_count'),
DB::raw('SUM(pbg_task_retributions.nilai_retribusi_bangunan) as total_retribution') DB::raw('SUM(ptr.nilai_retribusi_bangunan) as total_retribution')
) )
->first(); ->first();
$taskCount = $query->task_count; });
$taskTotal = $query->total_retribution; $taskCount = $query->task_count ?? 0;
$result = [ $taskTotal = $query->total_retribution ?? 0;
return $this->resSuccess([
"count" => $taskCount, "count" => $taskCount,
"series" => [$taskCount],
"total" => $taskTotal "total" => $taskTotal
]; ]);
return $this->resSuccess($result); }
public function verificationDocuments(Request $request){
$request->validate([
"year" => "required|integer"
]);
$current_year = $request->get('year');
$startOfYear = "$current_year-01-01 00:00:00";
$endOfYear = "$current_year-12-31 23:59:59";
$query = once( function () use ($startOfYear, $endOfYear){
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')
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
->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();
});
$taskCount = $query->total_data ?? 0;
$taskTotal = $query->total_retribution ?? 0;
return $this->resSuccess([
"count"=> $taskCount,
"total"=> $taskTotal
]);
}
public function nonVerificationDocuments(Request $request){
$request->validate([
"year" => "required|integer"
]);
$current_year = $request->get('year');
$startOfYear = "$current_year-01-01 00:00:00";
$endOfYear = "$current_year-12-31 23:59:59";
$query = once(function () use ($startOfYear, $endOfYear) {
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
->whereBetween("pt.task_created_at", [$startOfYear, $endOfYear])
->where(function ($query) {
$query->whereRaw('LOWER(TRIM(ptgs.status_verifikasi)) != ?', [strtolower(trim('Selesai Verifikasi'))])
->orWhereNull('ptgs.status_verifikasi'); // Include NULL values
})
->selectRaw('COUNT(pt.id) AS total_data,
SUM(ptr.nilai_retribusi_bangunan) AS total_retribution') // Menambahkan SUM dari pbg_task_retributions
->first();
});
$taskCount = $query->total_data ?? 0;
$taskTotal = $query->total_retribution ?? 0;
return $this->resSuccess([
"count"=> $taskCount,
"total"=> $taskTotal
]);
} }
public function pbgTaskDocuments(Request $request){ public function pbgTaskDocuments(Request $request){

View File

@@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\DataSettingRequest;
use App\Http\Resources\DataSettingResource;
use App\Models\DataSetting;
use App\Traits\GlobalApiResponse;
use Exception;
use Illuminate\Http\Request;
class DataSettingController extends Controller
{
use GlobalApiResponse;
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
try {
$query = DataSetting::query()->orderBy('id', 'desc');
if ($request->has("search") && !empty($request->get("search"))) {
$query = $query->where("key", $request->get("search"));
}
return DataSettingResource::collection($query->paginate());
} catch (Exception $e) {
return $this->resError($e->getMessage(), $e->getTrace());
}
}
/**
* Store a newly created resource in storage.
*/
public function store(DataSettingRequest $request)
{
try {
$data = DataSetting::create($request->validated());
$result = [
"success" => true,
"message" => "Data Setting created successfully",
"data" => new DataSettingResource($data)
];
return $this->resSuccess($result);
} catch (Exception $e) {
return $this->resError($e->getMessage(), $e);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
try {
$setting = DataSetting::findOrFail($id);
$result = [
"setting" => true,
"message" => "Data setting successfully",
"data" => new DataSettingResource($setting)
];
return $this->resSuccess($result);
} catch (Exception $e) {
return $this->resError($e->getMessage());
}
}
/**
* Update the specified resource in storage.
*/
public function update(DataSettingRequest $request, string $id)
{
try {
$data = DataSetting::findOrFail($id);
$data->update($request->validated());
$result = [
"success" => true,
"message" => "Data Setting updated successfully"
];
return $this->resSuccess($result);
} catch (Exception $e) {
return $this->resError($e->getMessage());
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try {
$setting = DataSetting::findOrFail($id);
$setting->delete();
$result = [
"success" => true,
"message" => "Data Setting deleted successfully"
];
return $this->resSuccess($result);
} catch (Exception $e) {
return $this->resError($e->getMessage());
}
}
}

View File

@@ -0,0 +1,61 @@
<?php
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()
{
$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)
{
//
}
/**
* 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)
{
//
}
}

View File

@@ -0,0 +1,31 @@
<?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;
class LackOfPotentialController extends Controller
{
public function count_lack_of_potential(){
try{
$total_reklame = Advertisement::count();
$total_pdam = Customer::count();
$total_tata_ruang = SpatialPlanning::count();
return response()->json([
'total_reklame' => $total_reklame,
'total_pdam' => $total_pdam,
'total_tata_ruang' => $total_tata_ruang
], 200);
}catch(\Exception $e){
return response()->json([
'message' => 'Error: '.$e->getMessage()
], 500);
}
}
}

View File

@@ -0,0 +1,109 @@
<?php
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
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$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());
}
/**
* Store a newly created resource in storage.
*/
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);
}
}
/**
* Display the specified resource.
*/
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(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);
}
}
/**
* Remove the specified resource from storage.
*/
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();
}
}
}

View File

@@ -0,0 +1,389 @@
<?php
namespace App\Http\Controllers\Api;
use App\Enums\ImportDatasourceStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\PbgTaskMultiStepRequest;
use App\Http\Resources\PbgTaskResource;
use App\Models\DataSetting;
use App\Models\ImportDatasource;
use App\Models\PbgTask;
use App\Models\PbgTaskGoogleSheet;
use App\Services\GoogleSheetService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class PbgTaskController extends Controller
{
protected $googleSheetService;
public function __construct(GoogleSheetService $googleSheetService){
$this->googleSheetService = $googleSheetService;
}
public function index(Request $request)
{
info($request);
$isLastUpdated = filter_var($request->query('isLastUpdated', false), FILTER_VALIDATE_BOOLEAN);
$query = PbgTask::query();
if ($isLastUpdated) {
$query->orderBy('updated_at', 'desc');
} else {
$query->where('status', 20);
}
// Ambil maksimal 10 data
$pbg_task = $query->limit(10)->get();
$totalData = $pbg_task->count();
// Tambahkan nomor urut
$data = $pbg_task->map(function ($item, $index) {
return array_merge($item->toArray(), ['no' => $index + 1]);
});
return response()->json([
'data' => $data,
'meta' => [
'total' => $totalData
]
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(PbgTaskMultiStepRequest $request)
{
try {
$data = PbgTask::create([
"uuid" => $request->input("step1Form.uuid"),
"name" => $request->input("step1Form.name"),
"owner_name" => $request->input("step1Form.owner_name"),
"application_type" => $request->input("step1Form.application_type"),
"application_type_name" => $request->input("step1Form.application_type_name"),
"condition" => $request->input("step1Form.condition"),
"registration_number" => $request->input("step1Form.registration_number"),
"document_number" => $request->input("step1Form.document_number"),
"address" => $request->input("step1Form.address"),
"status" => $request->input("step1Form.status"),
"status_name" => $request->input("step1Form.status_name"),
"slf_status" => $request->input("step1Form.slf_status"),
"slf_status_name" => $request->input("step1Form.slf_status_name"),
"function_type" => $request->input("step1Form.function_type"),
"consultation_type" => $request->input("step1Form.consultation_type"),
"due_date" => $request->input("step1Form.due_date"),
"land_certificate_phase" => $request->input("step1Form.land_certificate_phase"),
"task_created_at" => $request->input("step1Form.task_created_at"),
]);
return response()->json([
"success" => true,
"message" => "Step 1 berhasil disimpan!",
"data" => $data
], 201);
} catch (\Exception $e) {
return response()->json([
"success" => false,
"message" => "Gagal menyimpan data",
"error" => $e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
try{
$pbg_task = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations','pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id);
return response()->json([
"success"=> true,
"message"=> "Data ditemukan",
"data"=> $pbg_task
]);
}catch(\Exception $e){
return response()->json([
"success"=> false,
"message"=> $e->getMessage(),
]);
}
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
protected function validatePbgTask(Request $request){
return $request->validate([
"uuid" => $request->input("step1Form.uuid"),
]);
}
public function syncPbgFromGoogleSheet(){
$import_datasource = ImportDatasource::create([
"message" => "initialization",
"response_body" => null,
"status" => ImportDatasourceStatus::Processing->value,
]);
try{
$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"] = $row[2] ?? null;
$data_setting_result["MENUNGGU_KLIK_DPMPTSP_SUM"] = $row[3] ?? null;
} elseif ($found_section === "REALISASI_TERBIT_PBG") {
$data_setting_result["REALISASI_TERBIT_PBG_COUNT"] = $row[2] ?? null;
$data_setting_result["REALISASI_TERBIT_PBG_SUM"] = $row[4] ?? null;
} elseif ($found_section === "PROSES_DINAS_TEKNIS") {
$data_setting_result["PROSES_DINAS_TEKNIS_COUNT"] = $row[2] ?? null;
$data_setting_result["PROSES_DINAS_TEKNIS_SUM"] = $row[3] ?? null;
}
// Reset section tracking after capturing "Grand Total"
$found_section = null;
}
}
foreach ($data_setting_result as $key => $value) {
DataSetting::updateOrInsert(
["key" => $key], // Find by key
["value" => $value] // Update or insert value
);
}
$mapToUpsert = [];
$count = 0;
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,
];
}
DB::beginTransaction();
$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',
]);
}
$total_data = count($mapToUpsert);
$import_datasource->update([
"message" => "Successfully processed: {$total_data}",
"status" => ImportDatasourceStatus::Success->value,
]);
DB::commit();
return response()->json([
"success" => true,
"message" => "Data berhasil disimpan ke database"
], 200);
}catch(\Exception $ex){
DB::rollBack();
$import_datasource->update([
"message" => "Failed to importing",
"response_body" => $ex->getMessage(),
"status" => ImportDatasourceStatus::Failed->value,
]);
return response()->json([
"success" => false,
"message" => "Gagal menyimpan data",
"error" => $ex->getMessage()
], 500);
}
}
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;
}
// Otherwise, cast to integer
return (int) $value;
}
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;
}
}
}

View File

@@ -14,9 +14,10 @@ class RequestAssignmentController extends Controller
*/ */
public function index(Request $request) public function index(Request $request)
{ {
$query = PbgTask::query(); $query = PbgTask::query()->orderBy('id', 'desc');
if($request->has('search') && !empty($request->get("search"))){ if($request->has('search') && !empty($request->get("search"))){
$query->where('name', 'LIKE', '%'.$request->get('search').'%'); $query->where('name', 'LIKE', '%'.$request->get('search').'%')
->orWhere('registration_number', 'LIKE', '%'.$request->get('search').'%');
} }
return RequestAssignmentResouce::collection($query->paginate()); return RequestAssignmentResouce::collection($query->paginate());
} }

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\RoleRequest;
use App\Models\Role;
use Illuminate\Http\Request;
class RolesController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
$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());
}
/**
* Store a newly created resource in storage.
*/
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);
}
}
/**
* Display the specified resource.
*/
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(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);
}
}
/**
* Remove the specified resource from storage.
*/
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);
}
}
}

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\SpatialPlanning;
use Illuminate\Http\Request;
use App\Http\Requests\SpatialPlanningRequest;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\SpatialPlanningResource;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use App\Imports\SpatialPlanningImport;
use Illuminate\Support\Facades\Storage;
class SpatialPlanningController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request)
{
info($request);
$perPage = $request->input('per_page', 15);
$search = $request->input('search', '');
$query = SpatialPlanning::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('name', 'like', "%$search%")
->orWhere('kbli', 'like', "%$search%")
->orWhere('activities', 'like', "%$search%")
->orWhere('area', 'like', "%$search%")
->orWhere('location', 'like', "%$search%")
->orWhere('number', 'like', "%$search%");
});
}
$spatialPlannings = $query->paginate($perPage);
// Menambhakan nomor urut (No)
$start = ($spatialPlannings->currentPage()-1) * $perPage + 1;
// Tambahkan nomor urut ke dalam data
$data = $spatialPlannings->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
info($data);
return response()->json([
'data' => $data,
'meta' => [
'total' => $spatialPlannings->total(),
'per_page' => $spatialPlannings->perPage(),
'current_page' => $spatialPlannings->currentPage(),
'last_page'=>$spatialPlannings->lastPage(),
]
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(SpatialPlanningRequest $request): SpatialPlanning
{
$data = $request->validated();
return SpatialPlanning::create($data);
}
/**
* import spatial planning from excel
*/
public function importFromFile(Request $request)
{
info($request);
//validasi file
$validator = Validator::make($request->all(), [
'file' => 'required|mimes:xlsx, xls|max:10240'
]);
if ($validator->fails()) {
return response()->json([
'message'=>'File vaildation failed.',
"errors"=>$validator->errors()
], 400);
}
try {
$file = $request->file('file');
Excel::import(new SpatialPlanningImport, $file);
return response()->json([
'message'=>'File uploaded and imported successfully!'
], 200);
} catch (\Exception $e) {
return response()->json([
'message'=>'Error during file import.',
'error'=>$e->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(SpatialPlanning $spatialPlanning): SpatialPlanning
{
return $spatialPlanning;
}
/**
* Update the specified resource in storage.
*/
public function update(SpatialPlanningRequest $request, SpatialPlanning $spatialPlanning): SpatialPlanning
{
info($request);
$data = $request->validated();
info($data);
$spatialPlanning->update($data);
return $spatialPlanning;
}
public function destroy(SpatialPlanning $spatialPlanning): Response
{
$spatialPlanning->delete();
return response()->noContent();
}
public function downloadExcelSpatialPlanning()
{
$filePath = public_path('templates/template_spatial_planning.xlsx');
info(sprintf("File Path: %s | Exists: %s", $filePath, file_exists($filePath) ? 'Yes' : 'No'));
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
}

View File

@@ -21,11 +21,17 @@ class TourismController extends Controller
*/ */
public function index(Request $request) public function index(Request $request)
{ {
info($request);
$perPage = $request->input('per_page', 15); $perPage = $request->input('per_page', 15);
$search = $request->input('search', ''); $search = $request->input('search', '');
$query = Tourism::query(); $query = Tourism::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('business_name', 'like', "%$search%")
->orWhere('project_name', 'like', "%$search%")
->orWhere('business_address', 'like', "%$search%");
});
}
$tourisms = $query->paginate($perPage); $tourisms = $query->paginate($perPage);
$tourisms->getCollection()->transform(function ($tourisms) { $tourisms->getCollection()->transform(function ($tourisms) {
@@ -33,20 +39,23 @@ class TourismController extends Controller
$tourisms->village_name = $village ? $village->village_name : null; $tourisms->village_name = $village ? $village->village_name : null;
$district = DB::table('districts')->where('district_code', $tourisms->district_code)->first(); $district = DB::table('districts')->where('district_code', $tourisms->district_code)->first();
$tourisms->district_name = $district ? $district->district_name : null; $tourisms->district_name = $village ? $village->village_name : null;
$business_type = DB::table('business_type')->where('id', $tourisms->business_type_id)->first();
$tourisms->business_type = $business_type ? $business_type->business_type : null;
return $tourisms; return $tourisms;
}); });
$start = ($tourisms->currentPage()-1) * $perPage + 1;
$data = $tourisms->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
return response()->json([ return response()->json([
'data' => TourismResource::collection($tourisms), 'data' => $data,
'meta' => [ 'meta' => [
'total' => $tourisms->total(), 'total' => $tourisms->total(),
'per_page' => $tourisms->perPage(), 'per_page' => $tourisms->perPage(),
'current_page' => $tourisms->currentPage(), 'current_page' => $tourisms->currentPage(),
'last_page' => $tourisms->lastPage(), 'last_page'=>$tourisms->lastPage(),
] ]
]); ]);
} }
@@ -56,11 +65,18 @@ class TourismController extends Controller
*/ */
public function store(TourismRequest $request): Tourism public function store(TourismRequest $request): Tourism
{ {
return Tourism::create($request->validated()); $data = $request->validated();
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
$data['district_code'] = $district_code;
$data['village_code'] = $village_code;
return Tourism::create($data);
} }
/** /**
* Import advertisements from Excel or CSV * Import advertisements from Excel
*/ */
public function importFromFile(Request $request) public function importFromFile(Request $request)
{ {
@@ -71,8 +87,8 @@ class TourismController extends Controller
if ($validator->fails()) { if ($validator->fails()) {
return response()->json([ return response()->json([
'message' => 'File validation failed.', 'message'=>'File validation failed.',
'errors' => $validator->errors() 'errors'=>$validator->errors()
], 400); ], 400);
} }
@@ -80,16 +96,28 @@ class TourismController extends Controller
$file = $request->file('file'); $file = $request->file('file');
Excel::import(new TourismImport, $file); Excel::import(new TourismImport, $file);
return response()->json([ return response()->json([
'message' => 'File uploaded and imported successfully!' 'message'=>'File uploaded and imported successfully!'
], 200); ], 200);
} catch (\Exception $e) { } catch (\Exception $e) {
return response()->json([ return response()->json([
'message' => 'Error during file import.', 'message'=>'Error during file import.',
'error' => $e->getMessage() 'error'=>$e->getMessage()
], 500); ], 500);
} }
} }
public function getAllLocation()
{
$locations = Tourism::whereNotNull('longitude')
->whereNotNull('latitude')
->select('project_name', 'longitude', 'latitude')
->get();
return response()->json([
'data' => $locations
]);
}
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
@@ -103,7 +131,17 @@ class TourismController extends Controller
*/ */
public function update(TourismRequest $request, Tourism $tourism): Tourism public function update(TourismRequest $request, Tourism $tourism): Tourism
{ {
$tourism->update($request->validated()); $data = $request->validated();
// Cari district_code berdasarkan district_name
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
// Cari village_code berdasarkan village_name
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
// Tambahkan village_code dan district_code ke data
$data['village_code'] = $village_code;
$data['district_code'] = $district_code;
$tourism->update($data);
return $tourism; return $tourism;
} }
@@ -114,4 +152,18 @@ class TourismController extends Controller
return response()->noContent(); return response()->noContent();
} }
public function downloadExcelTourism()
{
$filePath = public_path('templates/template_pariwisata.xlsx');
info(sprintf("File Path: %s | Exists: %s", $filePath, file_exists($filePath) ? 'Yes' : 'No'));
// Cek apakah file ada
if (!file_exists($filePath)) {
return response()-> json(['message' => 'File tidak ditemukan!'], Response::HTTP_NOT_FOUND);
}
// Return file to download
return response()->download($filePath);
}
} }

View File

@@ -27,6 +27,17 @@ class UmkmController extends Controller
$query = Umkm::query(); $query = Umkm::query();
if ($search) {
$query->where(function ($q) use ($search) {
$q->where('business_name', 'like', "%$search%")
->orWhere('business_address', 'like', "%$search%")
->orWhere('business_desc', 'like', "%$search%")
->orWhere('business_id_number', 'like', "%$search%")
->orWhere('owner_id', 'like', "%$search%")
->orWhere('owner_name', 'like', "%$search%");
});
}
$umkm = $query->paginate($perPage); $umkm = $query->paginate($perPage);
$umkm->getCollection()->transform(function ($umkm) { $umkm->getCollection()->transform(function ($umkm) {
@@ -47,8 +58,14 @@ class UmkmController extends Controller
return $umkm; return $umkm;
}); });
$start = ($umkm->currentPage()-1) * $perPage + 1;
$data = $umkm->map(function ($item, $index) use ($start) {
return array_merge($item->toArray(), ['no' => $start + $index]);
});
return response()->json([ return response()->json([
'data' => UmkmResource::collection($umkm), 'data' => $data,
'meta' => [ 'meta' => [
'total' => $umkm->total(), 'total' => $umkm->total(),
'per_page' => $umkm->perPage(), 'per_page' => $umkm->perPage(),
@@ -69,9 +86,9 @@ class UmkmController extends Controller
// Cari kode berdasarkan nama // Cari kode berdasarkan nama
$district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code'); $district_code = DB::table('districts')->where('district_name', $data['district_name'])->value('district_code');
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code'); $village_code = DB::table('villages')->where('village_name', $data['village_name'])->where('district_code', $district_code)->value('village_code');
$business_scale_id = DB::table('business_scale')->where('id', $data['business_scale'])->value('id'); $business_scale_id = DB::table('business_scale')->where('id', $data['business_scale_id'])->value('id');
$permit_status_id = DB::table('permit_status')->where('id', $data['permit_status'])->value('id'); $permit_status_id = DB::table('permit_status')->where('id', $data['permit_status_id'])->value('id');
$business_form_id = DB::table('business_form')->where('id', $data['business_form'])->value('id'); $business_form_id = DB::table('business_form')->where('id', $data['business_form_id'])->value('id');
info($business_scale_id); info($business_scale_id);
@@ -176,7 +193,7 @@ class UmkmController extends Controller
public function downloadExcelUmkm() public function downloadExcelUmkm()
{ {
$filePath = storage_path('app/public/templateFile/template_umkm.xlsx'); $filePath = public_path('templates/template_umkm.xlsx');
// Cek apakah file ada // Cek apakah file ada
if (!file_exists($filePath)) { if (!file_exists($filePath)) {

View File

@@ -4,9 +4,11 @@ namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest; use App\Http\Requests\Auth\LoginRequest;
use App\Http\Requests\UsersRequest;
use App\Http\Resources\UserResource; use App\Http\Resources\UserResource;
use App\Models\User; use App\Models\User;
use App\Traits\GlobalApiResponse; use App\Traits\GlobalApiResponse;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -35,4 +37,50 @@ class UsersController extends Controller
$request->user()->tokens()->delete(); $request->user()->tokens()->delete();
return response()->json(['message' => 'logged out successfully']); return response()->json(['message' => 'logged out successfully']);
} }
public function store(UsersRequest $request){
$validate_data = $request->validated();
DB::beginTransaction();
try{
$user = User::create([
'name' => $validate_data['name'],
'email' => $validate_data['email'],
'password' => Hash::make($validate_data['password']),
'firstname' => $validate_data['firstname'],
'lastname' => $validate_data['lastname'],
'position' => $validate_data['position'],
]);
$user->roles()->attach((int) $validate_data['role_id']);
DB::commit();
return response()->json(['message' => 'Successfully created'],201);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
};
}
public function update(UsersRequest $request, $id){
try{
$validate_data = $request->validated();
$user = User::findOrFail($id);
DB::beginTransaction();
$user->update([
'name' => $validate_data['name'],
'email' => $validate_data['email'],
'firstname' => $validate_data['firstname'],
'lastname' => $validate_data['lastname'],
'position' => $validate_data['position']
]);
$user->roles()->sync($request->role_id);
DB::commit();
return response()->json(['message' => 'Successfully updated'], 200);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
}
}
} }

View 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)
{
//
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Http\Controllers;
use App\Models\BusinessOrIndustry;
use Illuminate\Http\Request;
class BusinessOrIndustriesController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('business-industries.index');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view("business-industries.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)
{
$data = BusinessOrIndustry::findOrFail($id);
return view('business-industries.edit', compact('data'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Models\Customer;
use Illuminate\Http\Request;
class CustomersController extends Controller
{
public function index()
{
return view('customers.index');
}
public function create()
{
return view('customers.create');
}
public function edit(string $id)
{
$data = Customer::findOrFail($id);
return view('customers.edit', compact('data'));
}
public function upload(){
return view('customers.upload');
}
}

View File

@@ -3,11 +3,20 @@
namespace App\Http\Controllers\Dashboards; namespace App\Http\Controllers\Dashboards;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\ImportDatasource;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class BigDataController extends Controller class BigDataController extends Controller
{ {
public function index(){ public function index(){
return view('dashboards.bigdata'); $latest_import_datasource = ImportDatasource::latest()->first();
$latest_created = $latest_import_datasource ?
$latest_import_datasource->created_at->format("j F Y H:i:s") : null;
return view('dashboards.bigdata', compact('latest_created'));
}
public function pbg()
{
return view('dashboards.pbg');
} }
} }

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers\Dashboards;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class LackOfPotentialController extends Controller
{
public function lack_of_potential(){
return view('dashboards.lack_of_potential');
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace App\Http\Controllers\Data;
use App\Http\Controllers\Controller;
use App\Models\SpatialPlanning;
use Illuminate\Http\Request;
class SpatialPlanningController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('data.spatialPlannings.index');
}
/**
* show the form for creating a new resource.
*/
public function bulkCreate()
{
return view('data.spatialPlannings.form-upload');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$title = 'Rencana Tata Ruang';
$subtitle = "Create Data";
// Mengambil data untuk dropdown
$dropdownOptions = [];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/spatial-plannings');
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* 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)
{
$title = 'Rencana Tata Ruang';
$subtitle = 'Update Data';
$modelInstance = SpatialPlanning::find($id);
// Pastikan model ditemukan
if (!$modelInstance) {
return redirect()->route('spatialPlanning.index') ->with('error', 'Rencana tata ruang tidak ditemukan');
}
$dropdownOptions = [];
$fields = $this->getFields();
$fieldTypes = $this->getFieldTypes();
$apiUrl = url('/api/spatial-plannings');
return view('data.spatialPlannings.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
private function getFields()
{
return [
"name"=> "Nama",
"kbli"=> "KBLI",
"activities"=> "Kegiatan",
"area"=> "Luas (m2)",
"location"=> "Lokasi",
"number"=> "Nomor",
"date"=> "Tanggal",
];
}
private function getFieldTypes()
{
return [
"name"=> "text",
"kbli"=> "text",
"activities"=> "text",
"area"=> "text",
"location"=> "text",
"number"=> "text",
"date"=> "date",
];
}
}

View File

@@ -36,8 +36,7 @@ class TourismController extends Controller
// Mengambil data untuk dropdown // Mengambil data untuk dropdown
$dropdownOptions = [ $dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'), 'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code'), 'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
'business_type_id' => DB::table('business_type')->orderBy('business_type')->pluck('business_type', 'id'),
]; ];
$fields = $this->getFields(); $fields = $this->getFields();
@@ -54,7 +53,7 @@ class TourismController extends Controller
public function edit($id) public function edit($id)
{ {
$title = 'Pariwisata'; $title = 'Pariwisata';
$subtitle = 'Create Data'; $subtitle = 'Update Data';
$modelInstance = Tourism::find($id); $modelInstance = Tourism::find($id);
// Pastikan model ditemukan // Pastikan model ditemukan
@@ -69,13 +68,9 @@ class TourismController extends Controller
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first(); $district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
$modelInstance->district_name = $district ? $district->district_name : null; $modelInstance->district_name = $district ? $district->district_name : null;
$business_type = DB::table('business_type')->where('id', $modelInstance->business_type_id)->first();
$modelInstance->business_scale_id = $business_type ? $business_type->id : null;
$dropdownOptions = [ $dropdownOptions = [
'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'), 'village_name' => DB::table('villages')->orderBy('village_name')->pluck('village_name', 'village_code'),
'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code'), 'district_name' => DB::table('districts')->orderBy('district_name')->pluck('district_name', 'district_code')
'business_type_id' => DB::table('business_type')->orderBy('business_type')->pluck('business_type', 'id'),
]; ];
$fields = $this->getFields(); $fields = $this->getFields();
@@ -89,30 +84,62 @@ class TourismController extends Controller
private function getFields() private function getFields()
{ {
return [ return [
"business_name" => "Nama Usaha", "project_id" => "ID Proyek",
"project_name" => "Nama Project", "project_type_id" => "Jenis Proyek",
"nib" => "NIB",
"business_name" => "Nama Perusahaan",
"oss_publication_date" => "Tanggal Terbit OSS",
"investment_status_description" => "Uraian Status Penanaman Modal",
"business_form" => "Uraian Jenis Perusahaan",
"project_risk" => "Risiko Proyek",
"project_name" => "Nama Proyek",
"business_scale" => "Uraian Skala Usaha",
"business_address" => "Alamat Usaha", "business_address" => "Alamat Usaha",
"district_name" => "Kecamatan", "district_name" => "Kecamatan",
"village_name" => "Desa", "village_name" => "Desa",
"land_area" => "Luas Tanah", "longitude" => "Longitude",
"latitude" => "Latitude",
"project_submission_date" => "Tanggal Pengajuan Project",
"kbli" => "KBLI",
"kbli_title" => "Judul KBLI",
"supervisory_sector" => "Sektor Pembina",
"user_name" => "Nama User",
"email" => "Email",
"contact" => "Kontak",
"land_area_in_m2" => "Luas Tanah (m2)",
"investment_amount" => "Jumlah Investasi", "investment_amount" => "Jumlah Investasi",
"number_of_employee" => "TKI", "tki" => "TKI",
"business_type_id" => "Jenis Usaha",
]; ];
} }
private function getFieldTypes() private function getFieldTypes()
{ {
return [ return [
"project_id" => "text",
"project_type_id" => "text",
"nib" => "text",
"business_name" => "text", "business_name" => "text",
"oss_publication_date" => "date",
"investment_status_description" => "text",
"business_form" => "text",
"project_risk" => "text",
"project_name" => "text", "project_name" => "text",
"business_address" => "textarea", "business_scale" => "text",
"business_address" => "text",
"district_name" => "combobox", "district_name" => "combobox",
"village_name" => "combobox", "village_name" => "combobox",
"land_area" => "text", "longitude" => "text",
"latitude" => "text",
"project_submission_date" => "date",
"kbli" => "text",
"kbli_title" => "text",
"supervisory_sector" => "text",
"user_name" => "text",
"email" => "text",
"contact" => "text",
"land_area_in_m2" => "text",
"investment_amount" => "text", "investment_amount" => "text",
"number_of_employee" => "text", "tki" => "text",
"business_type_id" => "select",
]; ];
} }
} }

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\DataSettingRequest;
use App\Models\DataSetting;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request;
class DataSettingController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view("data-settings.index");
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view("data-settings.create");
}
/**
* Store a newly created resource in storage.
*/
public function store(DataSettingRequest $request)
{
try{
DB::beginTransaction();
DataSetting::create($request->validated());
DB::commit();
return response()->json(['message' => 'Successfully created'],201);
}catch(Exception $ex){
DB::rollBack();
return response()->json([
'message' => 'Failed to create data setting',
'error' => $ex->getMessage()
], 500);
}
}
/**
* Display the specified resource.
*/
public function show(DataSetting $dataSetting)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
try{
$data = DataSetting::findOrFail($id);
if(empty($data)){
return redirect()->route('data-settings.index')->with('error', 'Invalid id');
}
return view("data-settings.edit", compact("data"));
}catch(Exception $ex){
return redirect()->route("data-settings.index")->with("error", "Invalid id");
}
}
/**
* Update the specified resource in storage.
*/
public function update(DataSettingRequest $request,string $id)
{
try{
DB::beginTransaction();
$data = DataSetting::findOrFail($id);
$data->update($request->validated());
DB::commit();
return response()->json(['message' => 'Successfully updated'], 200);
}catch(Exception $ex){
DB::rollBack();
return response()->json(['message' => $ex->getMessage()],500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
DB::beginTransaction();
DataSetting::findOrFail($id)->delete();
DB::commit();
return response()->json(['success' => true, 'message' => 'Item deleted successfully.'], 200);
}catch(Exception $e){
DB::rollBack();
Log::error($e->getMessage());
return response()->json(['success' => false, 'message' => 'Failed to delete item.'], 500);
}
}
public function getValueSetting(Request $request){
try{
$data = DataSetting::where('key', $request->key_name)->first();
return response()->json([
'success' => true,
'message' => "Successfully retrieved data",
"data"=> $data
]);
}catch(Exception $e){
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
}
}
}

View 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');
}
}

View File

@@ -3,7 +3,11 @@
namespace App\Http\Controllers\Master; namespace App\Http\Controllers\Master;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\UsersRequest;
use App\Models\Role;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules; use Illuminate\Validation\Rules;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use App\Models\User; use App\Models\User;
@@ -22,30 +26,40 @@ class UsersController extends Controller
return view('master.users.index', compact('users')); return view('master.users.index', compact('users'));
} }
public function create(){ public function create(){
return view('master.users.create'); $roles = Role::all();
return view('master.users.create', compact('roles'));
} }
public function store(Request $request){ public function store(UsersRequest $request){
$request->validate([ $request->validate([
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', 'max:255'], 'password' => ['required', 'confirmed', 'max:255'],
'firstname' => ['required', 'string', 'max:255'], 'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'], 'lastname' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'] 'position' => ['required', 'string', 'max:255'],
'role_id' => 'required|exists:roles,id'
]); ]);
// dd($request);
$user = User::create([ DB::beginTransaction();
'name' => $request->name, try{
'email' => $request->email, $user = User::create([
'password' => Hash::make($request->password), 'name' => $request->name,
'firstname' => $request->firstname, 'email' => $request->email,
'lastname' => $request->lastname, 'password' => Hash::make($request->password),
'position' => $request->position 'firstname' => $request->firstname,
]); 'lastname' => $request->lastname,
'position' => $request->position
]);
return redirect()->route('users.index')->with('success','Successfully registered'); $user->roles()->attach($request->role_id);
DB::commit();
return response()->json(['message' => 'Successfully created'],201);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
};
} }
public function show($id){ public function show($id){
$user = User::find($id); $user = User::find($id);
@@ -53,24 +67,40 @@ class UsersController extends Controller
} }
public function edit($id){ public function edit($id){
$user = User::find($id); $user = User::find($id);
return view('master.users.edit', compact('user')); $roles = Role::all();
return view('master.users.edit', compact('user', 'roles'));
} }
public function update(Request $request, $id){ public function update(Request $request, $id){
$user = User::find($id); $user = User::find($id);
$validate = $request->validate([ $validatedData = $request->validate([
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')->ignore($id)],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
'firstname' => ['required', 'string', 'max:255'], 'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'], 'lastname' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'] 'position' => ['required', 'string', 'max:255'],
'role_id' => ['required', 'exists:roles,id'],
]); ]);
$user->update($validate); try{
return redirect()->route('master.users')->with('success', 'Successfully'); DB::beginTransaction();
$updateData = [
'name' => $validatedData['name'],
'email' => $validatedData['email'],
'firstname' => $validatedData['firstname'],
'lastname' => $validatedData['lastname'],
'position' => $validatedData['position'],
];
$user->update($updateData);
$user->roles()->sync([$request->role_id]);
DB::commit();
return response()->json(['message' => 'Successfully updated'],200);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()],500);
}
} }
public function destroy($id){ public function destroy($id){
$user = User::find($id); $user = User::find($id);
$user->delete(); $user->delete();
return redirect()->route('master.users')->with('success','Successfully deleted'); return redirect()->route('users.index')->with('success','Successfully deleted');
} }
} }

View File

@@ -0,0 +1,113 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\MenuRequest;
use App\Models\Menu;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class MenusController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view('menus.index');
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
$parent_menus = Menu::whereNull('parent_id')->get();
return view("menus.create", compact('parent_menus'));
}
/**
* Store a newly created resource in storage.
*/
public function store(MenuRequest $request)
{
try{
$validated_menu = $request->validated();
DB::beginTransaction();
Menu::create($validated_menu);
DB::commit();
return response()->json(['message' => 'Successfully created'], 200);
}catch(\Exception $e){
DB::rollBack();
\Log::error('Menu creation failed: ' . $e->getMessage()); // Log the error for debugging
return response()->json(['message'=> $e->getMessage()],500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$menu = Menu::findOrFail($id);
$parent_menus = Menu::whereNull('parent_id')->where('id','!=',$id)->get();
return view("menus.edit", compact('menu','parent_menus'));
}
/**
* Update the specified resource in storage.
*/
public function update(MenuRequest $request, string $id)
{
try{
$validate_menu = $request->validated();
$menu = Menu::findOrFail($id);
DB::beginTransaction();
$menu->update($validate_menu);
DB::commit();
return response()->json(['message' => 'Successfully updated'], 200);
}catch(\Exception $e){
DB::rollBack();
\Log::error('Menu update failed: '. $e->getMessage()); // Log the error for debugging
return response()->json(['message' => $e->getMessage()],500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
DB::beginTransaction();
$menu = Menu::findOrFail($id);
$this->deleteChildren($menu);
$menu->roles()->detach();
$menu->delete();
DB::commit();
return response()->json(['success' => true, 'message' => 'Successfully deleted']);
}catch(\Exception $e){
DB::rollBack();
\Log::error('failed delete menu'. $e->getMessage());
return response()->json(['success' => false, 'message' => 'Something went wrong! Please try again.']);
}
}
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();
}
}
}

View File

@@ -3,7 +3,7 @@
namespace App\Http\Controllers\Report; namespace App\Http\Controllers\Report;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\BusinessTypeCount; use App\Models\TourismBasedKBLI;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@@ -14,8 +14,8 @@ class ReportTourismController extends Controller
*/ */
public function index() public function index()
{ {
$businessTypeCounts = BusinessTypeCount::all(); $tourismBasedKBLI = TourismBasedKBLI::all();
info($businessTypeCounts); info($tourismBasedKBLI);
return view('report.tourisms.index', compact('businessTypeCounts')); return view('report.tourisms.index', compact('tourismBasedKBLI'));
} }
} }

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers\RequestAssignment; namespace App\Http\Controllers\RequestAssignment;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\PbgTask;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class PbgTaskController extends Controller class PbgTaskController extends Controller
@@ -12,7 +13,7 @@ class PbgTaskController extends Controller
*/ */
public function index() public function index()
{ {
return view('request-assignment.index'); return view('pbg_task.index');
} }
/** /**
@@ -20,7 +21,7 @@ class PbgTaskController extends Controller
*/ */
public function create() public function create()
{ {
// return view("pbg_task.create");
} }
/** /**
@@ -28,7 +29,7 @@ class PbgTaskController extends Controller
*/ */
public function store(Request $request) public function store(Request $request)
{ {
//
} }
/** /**
@@ -36,7 +37,8 @@ class PbgTaskController extends Controller
*/ */
public function show(string $id) public function show(string $id)
{ {
// $data = PbgTask::with(['pbg_task_retributions','pbg_task_index_integrations', 'pbg_task_retributions.pbg_task_prasarana'])->findOrFail($id);
return view("pbg_task.show", compact("data"));
} }
/** /**
@@ -44,7 +46,7 @@ class PbgTaskController extends Controller
*/ */
public function edit(string $id) public function edit(string $id)
{ {
// return view("pbg_task.edit");
} }
/** /**

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\RoleRequest;
use App\Models\Menu;
use App\Models\Role;
use App\Models\RoleMenu;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
class RolesController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
return view("roles.index");
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view("roles.create");
}
/**
* Store a newly created resource in storage.
*/
public function store(RoleRequest $request)
{
try{
$validate_role = $request->validated();
DB::beginTransaction();
Role::create($validate_role);
DB::commit();
return response()->json(['message' => 'Role created successfully'], 201);
}
catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()], 500);
}
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
$role = Role::findOrFail($id);
return view("roles.edit", compact('role'));
}
/**
* Update the specified resource in storage.
*/
public function update(RoleRequest $request, string $id)
{
try{
$validate_role = $request->validated();
$role = Role::findOrFail($id);
DB::beginTransaction();
$role->update($validate_role);
DB::commit();
return response()->json(['message' => 'Role updated successfully'], 200);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['message' => $e->getMessage()], 500);
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
try{
DB::beginTransaction();
Role::findOrFail($id)->delete();
DB::commit();
return response()->json(['success' => true, "message" => "Successfully deleted"]);
}catch(\Exception $e){
DB::rollBack();
return response()->json(['success' => false, "message" => $e->getMessage()]);
}
}
public function menu_permission(string $role_id){
try{
$role = Role::findOrFail($role_id);
$menus = Menu::all();
$role_menus = RoleMenu::where('role_id', $role_id)->get() ?? collect();
return view('roles.role_menu', compact('role', 'menus', 'role_menus'));
}catch(\Exception $e){
return redirect()->back()->with("error", $e->getMessage());
}
}
public function update_menu_permission(Request $request, string $role_id){
try{
$validateData = $request->validate([
"permissions" => "array",
"permissions.*.allow_show" => "nullable|boolean",
"permissions.*.allow_create" => "nullable|boolean",
"permissions.*.allow_update" => "nullable|boolean",
"permissions.*.allow_destroy" => "nullable|boolean"
]);
$role = Role::find($role_id);
$permissionsArray = [];
foreach ($validateData['permissions'] as $menu_id => $permission) {
$permissionsArray[$menu_id] = [
"allow_show" => (int) ($permission["allow_show"] ?? 0),
"allow_create" => (int) ($permission["allow_create"] ?? 0),
"allow_update" => (int) ($permission["allow_update"] ?? 0),
"allow_destroy" => (int) ($permission["allow_destroy"] ?? 0),
"updated_at" => now(),
];
}
// Sync will update existing records and insert new ones
$role->menus()->sync($permissionsArray);
return redirect()->route("role-menu.permission", $role_id)->with('success','Menu Permission updated successfully');
}catch(\Exception $e){
Log::error("Error updating role_menu:", ["error" => $e->getMessage()]);
return redirect()->route("role-menu.permission", $role_id)->with("error", $e->getMessage());
}
}
}

View File

@@ -15,30 +15,4 @@ class RoutingController extends Controller
return redirect('auth.signin'); return redirect('auth.signin');
} }
} }
/**
* Display a view based on first route param
*
* @return \Illuminate\Http\Response
*/
public function root(Request $request, $first)
{
return view($first);
}
/**
* second level route
*/
public function secondLevel(Request $request, $first, $second)
{
return view($first . '.' . $second);
}
/**
* third level route
*/
public function thirdLevel(Request $request, $first, $second, $third)
{
return view($first . '.' . $second . '.' . $third);
}
} }

View File

@@ -3,37 +3,43 @@
namespace App\Http\Controllers\Settings; namespace App\Http\Controllers\Settings;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\ServiceSIMBG; use App\Services\ServiceSIMBG;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Exception; use Exception;
class SyncronizeController extends Controller class SyncronizeController extends Controller
{ {
protected $service_simbg;
public function __construct(ServiceSIMBG $service_simbg){
$this->service_simbg = $service_simbg;
}
public function index(Request $request){ public function index(Request $request){
return view('settings.syncronize.index'); return view('settings.syncronize.index');
} }
public function syncPbgTask(){ public function syncPbgTask(){
$res = (new ServiceSIMBG())->syncTaskList(); $res = $this->service_simbg->syncTaskList();
return $res; return $res;
} }
public function syncronizeTask(Request $request){ public function syncronizeTask(Request $request){
$res = (new ServiceSIMBG())->syncTaskList(); $res = $this->service_simbg->syncTaskList();
return redirect()->back()->with('success', 'Processing completed successfully'); return redirect()->back()->with('success', 'Processing completed successfully');
} }
public function getUserToken(){ public function getUserToken(){
$res = (new ServiceSIMBG())->getToken(); $res = $this->service_simbg->getToken();
return $res; return $res;
} }
public function syncIndexIntegration($uuid){ public function syncIndexIntegration(Request $request, $uuid){
$res = (new ServiceSIMBG())->syncIndexIntegration($uuid); $token = $request->get('token');
$res = $this->service_simbg->syncIndexIntegration($uuid, $token);
return $res; return $res;
} }
public function syncTaskDetailSubmit($uuid){ public function syncTaskDetailSubmit(Request $request, $uuid){
$res = (new ServiceSIMBG())->syncTaskDetailSubmit($uuid); $token = $request->get('token');
$res = $this->service_simbg->syncTaskDetailSubmit($uuid, $token);
return $res; return $res;
} }
} }

View File

@@ -40,4 +40,40 @@ class AdvertisementRequest extends FormRequest
'contact' => 'required|string', 'contact' => 'required|string',
]; ];
} }
/**
* pesan error validasi
*/
public function messages(): array
{
return [
'no.required' => 'Nomor harus diisi.',
'business_name.required' => 'Nama usaha harus diisi.',
'business_name.string' => 'Nama usaha harus berupa teks.',
'npwpd.required' => 'NPWPD harus diisi.',
'npwpd.string' => 'NPWPD harus berupa teks.',
'advertisement_type.required' => 'Jenis reklame harus diisi.',
'advertisement_type.string' => 'Jenis reklame harus berupa teks.',
'advertisement_content.required' => 'Isi reklame harus diisi.',
'advertisement_content.string' => 'Isi reklame harus berupa teks.',
'business_address.required' => 'Alamat usaha harus diisi.',
'business_address.string' => 'Alamat usaha harus berupa teks.',
'advertisement_location.required' => 'Lokasi reklame harus diisi.',
'advertisement_location.string' => 'Lokasi reklame harus berupa teks.',
'village_name.required' => 'Nama desa harus diisi.',
'district_name.required' => 'Nama kecamatan harus diisi.',
'length.required' => 'Panjang harus diisi.',
'width.required' => 'Lebar harus diisi.',
'viewing_angle.required' => 'Sudut pandang harus diisi.',
'viewing_angle.string' => 'Sudut pandang harus berupa teks.',
'face.required' => 'Jumlah sisi harus diisi.',
'face.string' => 'Jumlah sisi harus berupa teks.',
'area.required' => 'Luas harus diisi.',
'area.string' => 'Luas harus berupa teks.',
'angle.required' => 'Sudut harus diisi.',
'angle.string' => 'Sudut harus berupa teks.',
'contact.required' => 'Kontak harus diisi.',
'contact.string' => 'Kontak harus berupa teks.',
];
}
} }

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BusinessIndustryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'nama_kecamatan' => 'required|string|max:255',
'nama_kelurahan' => 'required|string|max:255',
'nop' => 'required|string|max:255|unique:business_or_industries,nop,' . $this->route('api_business_industry'),
'nama_wajib_pajak' => 'required|string|max:255',
'alamat_wajib_pajak' => 'nullable|string|max:255',
'alamat_objek_pajak' => 'required|string|max:255',
'luas_bumi' => 'required|numeric',
'luas_bangunan' => 'required|numeric',
'njop_bumi' => 'required|numeric',
'njop_bangunan' => 'required|numeric',
'ketetapan' => 'required|string|max:255',
'tahun_pajak' => 'required|integer|min:1900|max:' . date('Y'),
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CustomersRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'nomor_pelanggan' => ['required', 'string'],
'kota_pelayanan' => ['required', 'string'],
'nama' => ['required', 'string'],
'alamat' => ['required', 'string'],
'latitude' => ['required', 'numeric', 'between:-90,90'],
'longitude' => ['required', 'numeric', 'between:-180,180'],
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class DataSettingRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$id = $this->route('data_setting_id');
return [
"key" => "required|unique:data_settings,key," . $id,
"value" => "required",
"type" => "nullable",
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExcelUploadRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
"file" => "required|file|mimes:xlsx,xls|max:102400"
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class MenuRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$menuId = $this->route('menu_id'); // Get the menu ID if updating
return [
'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'],
];
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PbgTaskMultiStepRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules()
{
return [
// rules step 1
"step1Form.uuid" => "required",
"step1Form.name" => "nullable|string|max:255",
"step1Form.owner_name" => "nullable|string|max:255",
"step1Form.application_type" => "nullable|string|max:255",
"step1Form.application_type_name" => "nullable|string|max:255",
"step1Form.condition" => "nullable|string|max:255",
"step1Form.registration_number" => "nullable|string|max:255",
"step1Form.document_number" => "nullable|string|max:255",
"step1Form.address" => "nullable|string|max:255",
"step1Form.status" => "nullable|integer",
"step1Form.status_name" => "nullable|string|max:255",
"step1Form.slf_status" => "nullable|string|max:255",
"step1Form.slf_status_name" => "nullable|string|max:255",
"step1Form.function_type" => "nullable|string|max:255",
"step1Form.consultation_type" => "nullable|string|max:255",
"step1Form.due_date" => "nullable|date",
"step1Form.land_certificate_phase" => "nullable|boolean",
"step1Form.task_created_at" => "nullable|date",
];
}
public function messages()
{
return [
// message step 1
"step1Form.uuid.required" => "UUID wajib diisi.",
"step1Form.uuid.uuid" => "Format UUID tidak valid.",
"step1Form.name.max" => "Nama tidak boleh lebih dari 255 karakter.",
"step1Form.owner_name.max" => "Nama pemilik tidak boleh lebih dari 255 karakter.",
"step1Form.registration_number.max" => "Nomor registrasi tidak boleh lebih dari 255 karakter.",
"step1Form.document_number.max" => "Nomor dokumen tidak boleh lebih dari 255 karakter.",
"step1Form.status.integer" => "Status harus berupa angka.",
"step1Form.due_date.date" => "Tanggal jatuh tempo tidak valid.",
"step1Form.land_certificate_phase.boolean" => "Fase sertifikat tanah harus berupa true/false.",
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RoleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$roleId = $this->route('role_id');
return [
'name' => 'required|string|max:255|unique:roles,name,' . ($roleId ?? 'NULL') . ',id',
'description' => 'nullable|string',
];
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SpatialPlanningRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'string',
'kbli' => 'string',
'activities' => 'string',
'area' => 'string',
'location' => 'string',
'number' => 'string',
'date' => 'date_format:Y-m-d',
];
}
/**
* Get the validation messages for the defined validation rules.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'name.string' => 'Kolom Nama harus berupa teks.',
'kbli.string' => 'Kolom KBLI harus berupa teks.',
'activities.string' => 'Kolom Kegiatan harus berupa teks.',
'area.string' => 'Kolom Area harus berupa teks.',
'location.string' => 'Kolom Lokasi harus berupa teks.',
'number.string' => 'Kolom Nomor harus berupa teks.',
'date.date_format' => 'Format tanggal tidak valid, gunakan format Y-m-d H:i:s.',
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class SpatialPlanningsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => ['required','string','max:255'],
'kbli' => ['required','string','max:255'],
'kegiatan' => ['required','string'],
'luas' => ['required','numeric','regex:/^\d{1,16}(\.\d{1,2})?$/'],
'lokasi' => ['required','string'],
'nomor' => ['required','string','max:255',Rule::unique('spatial_plannings')->ignore($this->id)],
'sp_date' => ['required','date'],
];
}
}

View File

@@ -22,20 +22,112 @@ class TourismRequest extends FormRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'jenis_proyek' => 'string', 'project_id' => 'required|string',
'nib' => 'string', 'project_type_id' => 'required|string',
'nib' => 'required|string',
'business_name' => 'required|string', 'business_name' => 'required|string',
'status_penanaman_modal' => 'string', 'oss_publication_date' => 'required',
'business_form' => 'string', 'investment_status_description' => 'required|string',
'uraian_resiko_proyek' => 'string', 'business_form' => 'required|string',
'project_risk' => 'required|string',
'project_name' => 'required|string', 'project_name' => 'required|string',
'business_scale' => 'required|string',
'business_address' => 'required|string', 'business_address' => 'required|string',
'district_code' => 'required|string', 'district_name' => 'required',
'village_code' => 'required|string', 'village_name' => 'required',
'land_area' => 'required|string', 'longitude' => 'required|string',
'latitude' => 'required|string',
'project_submission_date' => 'required',
'kbli' => 'required|string',
'kbli_title' => 'required|string',
'supervisory_sector' => 'required|string',
'user_name' => 'required|string',
'email' => 'required|string',
'contact' => 'required|string',
'land_area_in_m2' => 'required|string',
'investment_amount' => 'required|string', 'investment_amount' => 'required|string',
'number_of_employee' => 'required|string', 'tki' => 'required|string',
'business_type_id' => 'required|string',
]; ];
} }
/**
* Get the validation messages for the defined validation rules.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'project_id.required' => 'ID proyek harus diisi.',
'project_id.string' => 'ID proyek harus berupa teks.',
'project_type_id.required' => 'ID tipe proyek harus diisi.',
'project_type_id.string' => 'ID tipe proyek harus berupa teks.',
'nib.required' => 'NIB harus diisi.',
'nib.string' => 'NIB harus berupa teks.',
'business_name.required' => 'Nama usaha harus diisi.',
'business_name.string' => 'Nama usaha harus berupa teks.',
'oss_publication_date.required' => 'Tanggal publikasi OSS harus diisi.',
'investment_status_description.required' => 'Deskripsi status investasi harus diisi.',
'investment_status_description.string' => 'Deskripsi status investasi harus berupa teks.',
'business_form.required' => 'Bentuk usaha harus diisi.',
'business_form.string' => 'Bentuk usaha harus berupa teks.',
'project_risk.required' => 'Risiko proyek harus diisi.',
'project_risk.string' => 'Risiko proyek harus berupa teks.',
'project_name.required' => 'Nama proyek harus diisi.',
'project_name.string' => 'Nama proyek harus berupa teks.',
'business_scale.required' => 'Skala usaha harus diisi.',
'business_scale.string' => 'Skala usaha harus berupa teks.',
'business_address.required' => 'Alamat usaha harus diisi.',
'business_address.string' => 'Alamat usaha harus berupa teks.',
'district_name.required' => 'Nama kecamatan harus diisi.',
'village_name.required' => 'Nama desa harus diisi.',
'longitude.required' => 'Garis bujur harus diisi.',
'longitude.string' => 'Garis bujur harus berupa teks.',
'latitude.required' => 'Garis lintang harus diisi.',
'latitude.string' => 'Garis lintang harus berupa teks.',
'project_submission_date.required' => 'Tanggal pengajuan proyek harus diisi.',
'kbli.required' => 'Kode KBLI harus diisi.',
'kbli.string' => 'Kode KBLI harus berupa teks.',
'kbli_title.required' => 'Judul KBLI harus diisi.',
'kbli_title.string' => 'Judul KBLI harus berupa teks.',
'supervisory_sector.required' => 'Sektor pengawasan harus diisi.',
'supervisory_sector.string' => 'Sektor pengawasan harus berupa teks.',
'user_name.required' => 'Nama pengguna harus diisi.',
'user_name.string' => 'Nama pengguna harus berupa teks.',
'email.required' => 'Email harus diisi.',
'email.string' => 'Email harus berupa teks.',
'contact.required' => 'Kontak harus diisi.',
'contact.string' => 'Kontak harus berupa teks.',
'land_area_in_m2.required' => 'Luas lahan dalam m² harus diisi.',
'land_area_in_m2.string' => 'Luas lahan dalam m² harus berupa teks.',
'investment_amount.required' => 'Jumlah investasi harus diisi.',
'investment_amount.string' => 'Jumlah investasi harus berupa teks.',
'tki.required' => 'Jumlah tenaga kerja Indonesia harus diisi.',
'tki.string' => 'Jumlah tenaga kerja Indonesia harus berupa teks.',
];
}
} }

View File

@@ -65,7 +65,7 @@ class UmkmRequest extends FormRequest
'business_id_number.string' => 'Nomor ID usaha harus berupa teks.', 'business_id_number.string' => 'Nomor ID usaha harus berupa teks.',
'business_scale.required' => 'Skala usaha wajib diisi.', 'business_scale_id.required' => 'Skala usaha wajib diisi.',
'owner_id.required' => 'ID pemilik wajib diisi.', 'owner_id.required' => 'ID pemilik wajib diisi.',
'owner_id.string' => 'ID pemilik harus berupa teks.', 'owner_id.string' => 'ID pemilik harus berupa teks.',
@@ -96,7 +96,7 @@ class UmkmRequest extends FormRequest
'number_of_employee.required' => 'Jumlah karyawan wajib diisi.', 'number_of_employee.required' => 'Jumlah karyawan wajib diisi.',
'permit_status.required' => 'Status izin wajib diisi.', 'permit_status_id.required' => 'Status izin wajib diisi.',
'land_area.required' => 'Luas lahan wajib diisi.', 'land_area.required' => 'Luas lahan wajib diisi.',
'land_area.integer' => 'Luas lahan harus berupa angka bulat.', 'land_area.integer' => 'Luas lahan harus berupa angka bulat.',

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UsersRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
$userId = $this->route('users'); // Get user ID from route (used in update)
return [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore($userId)
],
'password' => [$this->isMethod('post') ? 'required' : 'nullable', 'confirmed', 'max:255'],
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'],
'role_id' => ['required', 'exists:roles,id'],
];
}
}

View File

@@ -0,0 +1,42 @@
<?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, ',', '.'),
'year' => $this->year,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomersResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class DataSettingResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'key' => $this->key,
'value' => $this->value,
'type' => $this->type,
'created_at' => $this->created_at->toDateTimeString(),
'updated_at' => $this->updated_at->toDateTimeString(),
];
}
}

View 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);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SpatialPlanningResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SpatialPlanningsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
}

View File

@@ -23,6 +23,7 @@ class UserResource extends JsonResource
'position' => $this->position, 'position' => $this->position,
'firstname' => $this->firstname, 'firstname' => $this->firstname,
'lastname' => $this->lastname, 'lastname' => $this->lastname,
'roles' => $this->roles->pluck('name'),
]; ];
} }
} }

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Imports;
use App\Models\BusinessOrIndustry;
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, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection)
{
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;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace App\Imports;
use App\Models\Customer;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithLimit;
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 CustomersImport implements ToCollection, WithMultipleSheets, WithChunkReading, WithBatchInserts, ShouldQueue, WithHeadingRow
{
/**
* @param Collection $collection
*/
public function collection(Collection $collection)
{
$batchData = [];
$batchSize = 1000;
foreach ($collection as $row) {
if (!isset($row['nomor_pelanggan']) || empty($row['nomor_pelanggan'])) {
continue;
}
$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['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)) {
Customer::upsert($batchData, ['nomor_pelanggan'], ['kota_pelayanan', 'nama', 'alamat', 'latitude', 'longitude']);
}
}
public function sheets(): array {
return [
0 => $this
];
}
public function chunkSize(): int
{
return 1000;
}
public function batchSize(): int
{
return 1000;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Imports;
use App\Models\SpatialPlanning;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB;
use DateTime;
use Carbon\Carbon;
class SpatialPlanningImport implements ToCollection
{
protected static $processed = false;
/**
* Process each row in the file
*/
public function collection(Collection $rows)
{
if (self::$processed) {
return;
}
self::$processed = true;
if ($rows->isEmpty())
{
return;
}
//cari header secara otomatis
$header = $rows->first();
$headerIndex = collect($header)->search(fn($value) => !empty($value));
// Pastikan header ditemukan
if ($headerIndex === false) {
return;
}
foreach ($rows->skip(1) as $row) {
$dateValue = trim($row[7]);
info($dateValue);
$parsedDate = Carbon::createFromFormat('Y-m-d', $dateValue)->format('Y-m-d');
info($parsedDate);
$dataToInsert[] = [
'name'=>$row[1],
'kbli'=>$row[2],
'activities'=>$row[3],
'area'=>$row[4],
'location'=>$row[5],
'number'=>$row[6],
'date'=>$parsedDate,
];
}
if(!empty($dataToInsert)) {
SpatialPlanning::insert($dataToInsert);
} else {
return;
}
}
}

View File

@@ -7,6 +7,7 @@ use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use DateTime; use DateTime;
use Carbon\Carbon;
class TourismImport implements ToCollection class TourismImport implements ToCollection
{ {
@@ -42,12 +43,10 @@ class TourismImport implements ToCollection
return; return;
} }
info($rows);
foreach ($rows->skip(1) as $row) { foreach ($rows->skip(1) as $row) {
// Normalisasi nama kecamatan dan desa // Normalisasi nama kecamatan dan desa
$districtName = strtolower(trim(str_replace('Kecamatan', '', $row[13]))); $districtName = strtolower(trim(str_replace('Kecamatan', '', $row[12])));
$villageName = strtolower(trim($row[14])); $villageName = strtolower(trim($row[13]));
// Cari distric_code dari table districts // Cari distric_code dari table districts
$districtCode = $districts[$districtName] ?? null; $districtCode = $districts[$districtName] ?? null;
@@ -66,24 +65,42 @@ class TourismImport implements ToCollection
// ambill village code yang village_name sama dengan $villageName // ambill village code yang village_name sama dengan $villageName
$villageCode = $listTrueVillage[$villageName]['village_code'] ?? '000000'; $villageCode = $listTrueVillage[$villageName]['village_code'] ?? '000000';
$excelSerialDate = $row[16];
if (is_numeric($excelSerialDate)) {
$projectSubmissionDate = Carbon::createFromFormat('Y-m-d', '1899-12-30')
->addDays($excelSerialDate)
->format('Y-m-d H:i:s');
} else {
$projectSubmissionDate = Carbon::createFromFormat('m/d/Y', $excelSerialDate)
->format('Y-m-d H:i:s');
}
$dataToInsert[] = [ $dataToInsert[] = [
'project_id' => $row[1], 'project_id' => $row[1],
'jenis_proyek' => $row[2], 'project_type_id' => $row[2],
'nib' => $row[3], 'nib' => $row[3],
'business_name' => $row[4], 'business_name' => $row[4],
'terbit_oss' => DateTime::createFromFormat('d/m/Y', $row[5])->format('Y-m-d'), 'oss_publication_date' => DateTime::createFromFormat('d/m/Y', $row[5]),
'status_penanaman_modal' => $row[6], 'investment_status_description' => $row[6],
'business_form' => $row[7], 'business_form' => $row[7],
'uraian_resiko_proyek' => $row[8], 'project_risk' => $row[8],
'project_name' => $row[9], 'project_name' => $row[9],
'business_type_id' => $row[10], 'business_scale' => $row[10],
'business_scale_id' => (int) $row[11],
'business_address' => $row[12], 'business_address' => $row[12],
'district_code' => $districtCode, 'district_code' => $districtCode,
'village_code' => $villageCode, 'village_code' => $villageCode,
'land_area' => $row[15], 'longitude' => $row[14],
'investment_amount' => (string) $row[16], 'latitude' => (string) $row[15],
'number_of_employee' => (string) $row[17], 'project_submission_date' => $projectSubmissionDate,
'kbli'=> $row[17],
'kbli_title'=>$row[18],
'supervisory_sector'=>$row[19],
'user_name'=>$row[20],
'email'=>$row[21],
'contact'=>$row[22],
'land_area_in_m2'=>$row[23],
'investment_amount'=>$row[24],
'tki'=>$row[25]
]; ];
} }

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class BigdataResume extends Model
{
protected $table = "bigdata_resumes";
protected $fillable = [
'import_datasource_id',
'potention_count',
'potention_sum',
'non_verified_count',
'non_verified_sum',
'verified_count',
'verified_sum',
'business_count',
'business_sum',
'non_business_count',
'non_business_sum',
'spatial_count',
'spatial_sum',
'year'
];
public function importDatasource()
{
return $this->belongsTo(ImportDatasource::class, 'import_datasource_id');
}
public static function generateResumeData($import_datasource_id, $year){
$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);
})
->selectRaw("
COUNT(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) = 'selesai verifikasi' THEN 1 END) AS verified_count,
SUM(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) = 'selesai verifikasi' THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS verified_total,
COUNT(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL THEN 1 END) AS non_verified_count,
SUM(CASE WHEN LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_verified_total,
COUNT(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
AND LOWER(TRIM(pbg_task.function_type)) = 'sebagai tempat usaha' THEN 1 END) AS business_count,
SUM(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
AND LOWER(TRIM(pbg_task.function_type)) = 'sebagai tempat usaha' THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS business_total,
COUNT(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
AND (LOWER(TRIM(pbg_task.function_type)) != 'sebagai tempat usaha' OR pbg_task.function_type IS NULL) THEN 1 END) AS non_business_count,
SUM(CASE WHEN (LOWER(TRIM(ptgs.status_verifikasi)) != 'selesai verifikasi' OR ptgs.status_verifikasi IS NULL)
AND (LOWER(TRIM(pbg_task.function_type)) != 'sebagai tempat usaha' OR pbg_task.function_type IS NULL) THEN ptr.nilai_retribusi_bangunan ELSE 0 END) AS non_business_total
")
->first();
// 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();
});
$potention_count = $query_potention->task_count ?? 0;
$potention_total = $query_potention->total_retribution ?? 0;
$query_spatial_plannings = once(function () use ($year) {
$query = PbgTask::join('spatial_plannings as sp', 'pbg_task.document_number', '=', 'sp.number')
->join('pbg_task_retributions as ptr', 'ptr.pbg_task_uid', '=', 'pbg_task.uuid')
->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();
});
$spatial_planning_count = $query_spatial_plannings->task_count ?? 0;
$spatial_planning_total = $query_spatial_plannings->total_retribution ?? 0;
$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,
'non_verified_sum' => $non_verified_total ?? 0.00,
'verified_count' => $verified_count ?? 0,
'verified_sum' => $verified_total ?? 0.00,
'business_count' => $business_count ?? 0,
'business_sum' => $business_total ?? 0.00,
'non_business_count' => $non_business_count ?? 0,
'non_business_sum' => $non_business_total ?? 0.00,
'year' => $year
]);
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BusinessOrIndustry extends Model
{
protected $table = "business_or_industries";
protected $fillable = [
'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',
];
}

View File

@@ -1,14 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BusinessTypeCount extends Model
{
protected $table = 'business_type_counts';
protected $primaryKey = null;
public $timestamps = false;
protected $fillable = ['business_type', 'count'];
}

20
app/Models/Customer.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
protected $table = 'customers';
protected $fillable = [
'nomor_pelanggan',
'kota_pelayanan',
'nama',
'alamat',
'latitude',
'longitude',
];
}

View File

@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DataSetting extends Model
{
protected $table = "data_settings";
protected $fillable = [
"key",
"value",
"type"
];
}

25
app/Models/Menu.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model
{
protected $table = 'menus';
protected $fillable = [
'name',
'url',
'icon',
'parent_id',
'sort_order'
];
public function roles(){
return $this->belongsToMany(Role::class, 'role_menu')->withTimestamps();
}
public function children(){
return $this->hasMany(Menu::class,'parent_id');
}
}

View File

@@ -30,7 +30,15 @@ class PbgTask extends Model
'task_created_at' 'task_created_at'
]; ];
public function retributions(){ public function pbg_task_retributions(){
return $this->hasOne(PbgTaskRetributions::class, 'pbg_task_uid', 'uuid'); return $this->hasOne(PbgTaskRetributions::class, 'pbg_task_uid', 'uuid');
} }
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');
}
} }

View File

@@ -0,0 +1,68 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PbgTaskGoogleSheet extends Model
{
protected $table = "pbg_task_google_sheet";
protected $fillable = [
'jenis_konsultasi',
'no_registrasi',
'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',
];
}

View File

@@ -21,4 +21,8 @@ class PbgTaskIndexIntegrations extends Model
'indeks_terintegrasi', 'indeks_terintegrasi',
'total', 'total',
]; ];
public function pbg_task(){
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
}
} }

View File

@@ -20,5 +20,10 @@ class PbgTaskPrasarana extends Model
'quantity', 'quantity',
'unit', 'unit',
'index_prasarana', 'index_prasarana',
'pbg_task_retribution_id'
]; ];
public function pbg_task_retributions(){
return $this->hasMany(PbgTaskRetributions::class, 'pbg_task_retribution_id', 'id');
}
} }

View File

@@ -32,7 +32,11 @@ class PbgTaskRetributions extends Model
'pbg_task_uid' 'pbg_task_uid'
]; ];
public function task(){ public function pbg_task(){
return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid'); return $this->belongsTo(PbgTask::class, 'pbg_task_uid', 'uuid');
} }
public function pbg_task_prasarana(){
return $this->hasMany(PbgTaskPrasarana::class, 'pbg_task_retribution_id', 'id');
}
} }

22
app/Models/Role.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
protected $table = 'roles';
protected $fillable = [
'name',
'description'
];
public function users(){
return $this->belongsToMany(User::class,'user_role')->withTimestamps();
}
public function menus(){
return $this->belongsToMany(Menu::class,'role_menu')->withTimestamps();
}
}

30
app/Models/RoleMenu.php Normal file
View File

@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class RoleMenu extends Model
{
protected $table = 'role_menu';
protected $primary = ['role_id', 'menu_id'];
public $incrementing = false;
protected $fillable = [
'role_id',
'menu_id',
'allow_show',
'allow_create',
'allow_update',
'allow_destroy',
];
public $timestamps = true;
public function role(){
return $this->belongsTo(Role::class, 'role_id');
}
public function menu(){
return $this->belongsTo(Menu::class,'menu_id');
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Class SpatialPlanning
*
* @property $id
* @property $created_at
* @property $updated_at
* @property $name
* @property $kbli
* @property $activities
* @property $area
* @property $location
* @property $number
* @property $date
*
* @package App
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class SpatialPlanning extends Model
{
protected $perPage = 20;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = ['name', 'kbli', 'activities', 'area', 'location', 'number', 'date'];
}

View File

@@ -8,25 +8,33 @@ use Illuminate\Database\Eloquent\Model;
* Class Tourism * Class Tourism
* *
* @property $id * @property $id
* @property $project_id
* @property $jenis_proyek
* @property $nib
* @property $created_at * @property $created_at
* @property $updated_at * @property $updated_at
* @property $project_id
* @property $project_type_id
* @property $nib
* @property $business_name * @property $business_name
* @property $terbit_oss * @property $oss_publication_date
* @property $status_penanaman_modal * @property $investment_status_description
* @property $business_form * @property $business_form
* @property $uraian_resiko_proyek * @property $project_risk
* @property $project_name * @property $project_name
* @property $business_scale_id * @property $business_scale
* @property $business_address * @property $business_address
* @property $district_code * @property $district_code
* @property $village_code * @property $village_code
* @property $land_area * @property $longitude
* @property $latitude
* @property $project_submission_date
* @property $kbli
* @property $kbli_title
* @property $supervisory_sector
* @property $user_name
* @property $email
* @property $contact
* @property $land_area_in_m2
* @property $investment_amount * @property $investment_amount
* @property $number_of_employee * @property $tki
* @property $business_type_id
* *
* @package App * @package App
* @mixin \Illuminate\Database\Eloquent\Builder * @mixin \Illuminate\Database\Eloquent\Builder
@@ -41,7 +49,7 @@ class Tourism extends Model
* *
* @var array<int, string> * @var array<int, string>
*/ */
protected $fillable = ['project_id', 'jenis_proyek', 'nib', 'business_name', 'terbit_oss', 'status_penanaman_modal', 'business_form', 'uraian_resiko_proyek', 'project_name', 'business_scale_id', 'business_address', 'district_code', 'village_code', 'land_area', 'investment_amount', 'number_of_employee', 'business_type_id']; protected $fillable = ['project_id', 'project_type_id', 'nib', 'business_name', 'oss_publication_date', 'investment_status_description', 'business_form', 'project_risk', 'project_name', 'business_scale', 'business_address', 'district_code', 'village_code', 'longitude', 'latitude', 'project_submission_date', 'kbli', 'kbli_title', 'supervisory_sector', 'user_name', 'email', 'contact', 'land_area_in_m2', 'investment_amount', 'tki'];
} }

View File

@@ -0,0 +1,14 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TourismBasedKBLI extends Model
{
protected $table = 'v_tourisms_based_kbli';
protected $primaryKey = null;
public $timestamps = false;
protected $fillable = ['kbli_title', 'total_records'];
}

View File

@@ -49,4 +49,8 @@ class User extends Authenticatable
'password' => 'hashed', 'password' => 'hashed',
]; ];
} }
public function roles(){
return $this->belongsToMany(Role::class, 'user_role')->withTimestamps();
}
} }

View File

@@ -2,8 +2,11 @@
namespace App\Providers; namespace App\Providers;
use App\Models\Menu;
use App\View\Components\Circle; use App\View\Components\Circle;
use Auth;
use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Carbon\Carbon; use Carbon\Carbon;
@@ -23,5 +26,26 @@ class AppServiceProvider extends ServiceProvider
public function boot(): void public function boot(): void
{ {
Blade::component('circle', Circle::class); Blade::component('circle', Circle::class);
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{
$menus = collect();
}
$view->with('menus', $menus);
});
} }
} }

View File

@@ -1,296 +0,0 @@
<?php
namespace App;
use App\Enums\ImportDatasourceStatus;
use App\Models\GlobalSetting;
use App\Models\ImportDatasource;
use App\Models\PbgTaskIndexIntegrations;
use App\Models\PbgTaskPrasarana;
use App\Models\PbgTaskRetributions;
use Exception;
use App\Models\PbgTask;
use App\Traits\GlobalApiResponse;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
class ServiceSIMBG
{
use GlobalApiResponse;
private $email;
private $password;
private $simbg_host;
private $fetch_per_page;
/**
* Create a new class instance.
*/
public function __construct()
{
$this->email = trim((string) GlobalSetting::where('key','SIMBG_EMAIL')->first()->value);
$this->password = trim((string) GlobalSetting::where('key','SIMBG_PASSWORD')->first()->value);
$this->simbg_host = trim((string)GlobalSetting::where('key','SIMBG_HOST')->first()->value);
$this->fetch_per_page = trim((string)GlobalSetting::where('key','FETCH_PER_PAGE')->first()->value);
}
public function getToken(){
$clientHelper = new ServiceClient($this->simbg_host);
$url = "/api/user/v1/auth/login/";
$body = [
'email' => $this->email,
'password' => $this->password,
];
$res = $clientHelper->post($url, $body);
if(!$res->original['success']){
Log::error("Token not retrieved ", ['response' => $res]);
return null;
}
return $res;
}
public function syncIndexIntegration($uuid, $token)
{
$clientHelper = new ServiceClient($this->simbg_host);
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
$headers = [
'Authorization' => "Bearer " . $token,
];
$res = $clientHelper->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;
}
$data = $res->original['data']['data'] ?? null;
if (!$data) {
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
return false;
}
$resultData = PbgTaskIndexIntegrations::updateOrCreate(
['pbg_task_uid' => $uuid],
[
'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null,
'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null,
'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null,
'indeks_parameter_ketinggian' => $data['indeks_parameter_ketinggian'] ?? null,
'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null,
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
'total' => $data['total'] ?? null,
]
);
// Log success
if ($resultData->wasRecentlyCreated) {
Log::info("integration created successfully", ['uuid' => $uuid]);
} else {
Log::info("integration updated successfully", ['uuid' => $uuid]);
}
return true;
}
public function syncTaskList()
{
$clientHelper = new ServiceClient($this->simbg_host);
$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'
]);
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 = $clientHelper->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();
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 = $clientHelper->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;
}
}
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'
]);
}
$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]);
}
public function syncTaskDetailSubmit($uuid, $token)
{
$clientHelper = new ServiceClient($this->simbg_host);
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
$headers = [
'Authorization' => "Bearer " . $token,
];
$res = $clientHelper->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;
}
$data = $res->original['data']['data'] ?? [];
if (empty($data)) {
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
return false;
}
$detailCreatedAt = isset($data['created_at'])
? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s')
: null;
$detailUpdatedAt = isset($data['updated_at'])
? Carbon::parse($data['updated_at'])->format('Y-m-d H:i:s')
: null;
PbgTaskRetributions::updateOrCreate(
['detail_id' => $data['id']],
[
'detail_uid' => $data['uid'] ?? null,
'detail_created_at' => $detailCreatedAt ?? null,
'detail_updated_at' => $detailUpdatedAt ?? null,
'luas_bangunan' => $data['luas_bangunan'] ?? null,
'indeks_lokalitas' => $data['indeks_lokalitas'] ?? null,
'wilayah_shst' => $data['wilayah_shst'] ?? null,
'kegiatan_id' => $data['kegiatan']['id'] ?? null,
'kegiatan_name' => $data['kegiatan']['name'] ?? null,
'nilai_shst' => $data['nilai_shst'] ?? null,
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
'indeks_bg_terbangun' => $data['indeks_bg_terbangun'] ?? null,
'nilai_retribusi_bangunan' => $data['nilai_retribusi_bangunan'] ?? null,
'nilai_prasarana' => $data['nilai_prasarana'] ?? null,
'created_by' => $data['created_by'] ?? null,
'pbg_document' => $data['pbg_document'] ?? null,
'underpayment' => $data['underpayment'] ?? null,
'skrd_amount' => $data['skrd_amount'] ?? null,
'pbg_task_uid' => $uuid,
]
);
$prasaranaData = $data['prasarana'] ?? [];
if (!empty($prasaranaData)) {
$insertData = array_map(fn($item) => [
'pbg_task_uid' => $uuid,
'prasarana_id' => $item['id'] ?? null,
'prasarana_type' => $item['prasarana_type'] ?? null,
'building_type' => $item['building_type'] ?? null,
'total' => $item['total'] ?? null,
'quantity' => $item['quantity'] ?? null,
'unit' => $item['unit'] ?? null,
'index_prasarana' => $item['index_prasarana'] ?? null,
], $prasaranaData);
// Use bulk insert or upsert for faster database operation
PbgTaskPrasarana::upsert($insertData, ['pbg_task_uid', 'prasarana_id']);
}
Log::info("retribution and prasarana successfully", ['uuid' => $uuid]);
return true;
}
}

View File

@@ -0,0 +1,152 @@
<?php
namespace App\Services;
use Google_Client;
use Google_Service_Sheets;
class GoogleSheetService
{
/**
* Create a new class instance.
*/
protected $client;
protected $service;
protected $spreadsheetID;
public function __construct()
{
$this->client = new Google_Client();
$this->client->setApplicationName("Sibedas Google Sheets API");
$this->client->setScopes([Google_Service_Sheets::SPREADSHEETS_READONLY]);
$this->client->setAuthConfig(storage_path("app/teak-banner-450003-s8-ea05661d9db0.json"));
$this->client->setAccessType("offline");
$this->service = new Google_Service_Sheets($this->client);
$this->spreadsheetID = env("SPREAD_SHEET_ID");
$this->service_sheets = new Google_Service_Sheets($this->client);
}
public function getSheetData($range){
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
return $response->getValues();
}
public function getLastRowByColumn($column = "A")
{
try{
// Ambil spreadsheet
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
if (!empty($sheets)) {
// Ambil nama sheet pertama dengan benar
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// ✅ Format range harus benar!
$range = "{$firstSheetTitle}!{$column}:{$column}";
// Ambil data dari kolom yang diminta
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Cek nilai terakhir yang tidak kosong
$lastRow = 0;
if (!empty($values)) {
foreach ($values as $index => $row) {
if (!empty($row[0])) { // Jika ada data, update lastRow
$lastRow = $index + 1;
}
}
}
return $lastRow;
}
return 0;
}catch(\Exception $e){
throw $e;
}
}
public function getHeader()
{
try{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
// Ambil nama sheet pertama
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// Ambil data dari baris pertama (header)
$range = "{$firstSheetTitle}!1:1";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Kembalikan header (baris pertama)
return !empty($values) ? $values[0] : [];
}catch(\Exception $e){
throw $e;
}
}
public function getLastColumn()
{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
// Ambil nama sheet pertama
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
// Ambil baris pertama untuk mendapatkan jumlah kolom yang terisi
$range = "{$firstSheetTitle}!1:1";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
// Hitung jumlah kolom yang memiliki nilai
return !empty($values) ? count(array_filter($values[0], fn($value) => $value !== "")) : 0;
}
public function getSheetDataCollection($totalRow = 10){
try{
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
$firstSheetTitle = $sheets[0]->getProperties()->getTitle();
$header = $this->getHeader();
$header = array_map(function($columnHeader) {
// Trim spaces first, then replace non-alphanumeric characters with underscores
$columnHeader = trim($columnHeader);
return strtolower(preg_replace('/[^A-Za-z0-9_]/', '_', $columnHeader));
}, $header);
$range = "{$firstSheetTitle}!2:{$totalRow}";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
$mappedData = [];
if (!empty($values)) {
foreach ($values as $row) {
$rowData = [];
foreach ($header as $index => $columnHeader) {
// Map header to the corresponding value from the row
$rowData[$columnHeader] = isset($row[$index]) ? $row[$index] : null;
}
$mappedData[] = $rowData;
}
}
return $mappedData;
}catch(\Exception $e){
throw $e;
}
}
public function get_data_by_sheet($no_sheet = 1){
$spreadsheet = $this->service->spreadsheets->get($this->spreadsheetID);
$sheets = $spreadsheet->getSheets();
$sheetTitle = $sheets[$no_sheet]->getProperties()->getTitle();
$range = "{$sheetTitle}";
$response = $this->service->spreadsheets_values->get($this->spreadsheetID, $range);
$values = $response->getValues();
return!empty($values)? $values : [];
}
}

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace App; namespace App\Services;
use App\Traits\GlobalApiResponse; use App\Traits\GlobalApiResponse;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use Exception; use Exception;
@@ -26,7 +26,7 @@ class ServiceClient
); );
} }
public function makeRequest($url, $method = 'GET', $body = null, $headers = [], $timeout = 300){ public function makeRequest($url, $method = 'GET', $body = null, $headers = [], $timeout = 14400){
try { try {
$headers = array_merge($this->headers, $headers); $headers = array_merge($this->headers, $headers);
@@ -42,10 +42,17 @@ class ServiceClient
} }
$response = $this->client->request($method, $this->baseUrl . $url, $options); $response = $this->client->request($method, $this->baseUrl . $url, $options);
$responseBody = (string) $response->getBody();
$resultResponse = json_decode($response->getBody(), true); if (!str_contains($response->getHeaderLine('Content-Type'), 'application/json')) {
\Log::error('Unexpected response format: ' . $responseBody);
return $this->resError('API response is not JSON');
}
$resultResponse = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
return $this->resSuccess($resultResponse); return $this->resSuccess($resultResponse);
} catch (Exception $e) { } catch (Exception $e) {
\Log::error('error from client service'. $e->getMessage());
return $this->resError($e->getMessage()); return $this->resError($e->getMessage());
} }
} }

View File

@@ -0,0 +1,328 @@
<?php
namespace App\Services;
use App\Enums\ImportDatasourceStatus;
use App\Models\BigdataResume;
use App\Models\GlobalSetting;
use App\Models\ImportDatasource;
use App\Models\PbgTaskIndexIntegrations;
use App\Models\PbgTaskPrasarana;
use App\Models\PbgTaskRetributions;
use Exception;
use App\Models\PbgTask;
use App\Traits\GlobalApiResponse;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use App\Services\ServiceClient;
class ServiceSIMBG
{
use GlobalApiResponse;
private $email;
private $password;
private $simbg_host;
private $fetch_per_page;
private $service_client;
/**
* Create a new class instance.
*/
public function __construct()
{
$settings = GlobalSetting::whereIn('key', [
'SIMBG_EMAIL', 'SIMBG_PASSWORD', 'SIMBG_HOST', 'FETCH_PER_PAGE'
])->pluck('value', 'key');
$this->email = trim((string) ($settings['SIMBG_EMAIL'] ?? ""));
$this->password = trim((string) ($settings['SIMBG_PASSWORD'] ?? ""));
$this->simbg_host = trim((string) ($settings['SIMBG_HOST'] ?? ""));
$this->fetch_per_page = trim((string) ($settings['FETCH_PER_PAGE'] ?? ""));
$this->service_client = new ServiceClient($this->simbg_host);
}
public function getToken(){
try{
$url = "/api/user/v1/auth/login/";
$body = [
'email' => $this->email,
'password' => $this->password,
];
$res = $this->service_client->post($url, $body);
if(!$res->original['success']){
Log::error("Token not retrieved ", ['response' => $res]);
throw new Exception("Token not retrieved.");
}
return $res;
}catch(Exception $e){
Log::error("Error on method get token ", ['response' => $e->getMessage()]);
throw $e;
}
}
public function syncIndexIntegration($uuids, $token)
{
try{
if(empty($uuids)){
return false;
}
$integrations = [];
foreach($uuids as $uuid){
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/indeks-terintegrasi/";
$headers = [
'Authorization' => "Bearer " . $token,
];
$res = $this->service_client->get($url, $headers);
if (empty($res->original['success']) || !$res->original['success']) {
// Log error
Log::error("API response indicates failure", ['url' => $url, 'uuid' => $uuid]);
continue;
}
$data = $res->original['data']['data'] ?? null;
if (!$data) {
Log::error("No valid data returned from API", ['url' => $url, 'uuid' => $uuid]);
continue;
}
$integrations[] = [
'pbg_task_uid' => $uuid,
'indeks_fungsi_bangunan' => $data['indeks_fungsi_bangunan'] ?? null,
'indeks_parameter_kompleksitas' => $data['indeks_parameter_kompleksitas'] ?? null,
'indeks_parameter_permanensi' => $data['indeks_parameter_permanensi'] ?? null,
'indeks_parameter_ketinggian' => $data['indeks_parameter_ketinggian'] ?? null,
'faktor_kepemilikan' => $data['faktor_kepemilikan'] ?? null,
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
'total' => $data['total'] ?? null,
];
}
PbgTaskIndexIntegrations::upsert($integrations, ['pbg_task_uid'], ['indeks_fungsi_bangunan',
'indeks_parameter_kompleksitas', 'indeks_parameter_permanensi', 'indeks_parameter_ketinggian', 'faktor_kepemilikan', 'indeks_terintegrasi', 'total']);
return true;
}catch (Exception $e){
Log::error('error when sync index integration ', ['index integration'=> $e->getMessage()]);
throw $e;
}
}
public function syncTaskList()
{
try {
$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'
]);
return $this->resError("Failed to retrieve token");
}
$initResToken = $this->getToken();
$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++) {
try {
$pageUrl = "/api/pbg/v1/list/?page={$currentPage}&size={$this->fetch_per_page}&sort=ASC";
Log::info("Fetching tasks", ['currentPage' => $currentPage]);
$response = $this->service_client->get($pageUrl, $headers);
$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);
$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, $apiToken);
}
} 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");
BigdataResume::generateResumeData($importDatasource->id, now()->year);
// 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,
'message' => 'Critical failure: ' . $e->getMessage()
]);
}
return $this->resError("Critical failure occurred: " . $e->getMessage());
}
}
public function syncTaskDetailSubmit($uuid, $token)
{
try{
$url = "/api/pbg/v1/detail/" . $uuid . "/retribution/submit/";
$headers = [
'Authorization' => "Bearer " . $token,
];
$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;
}
$data = $res->original['data']['data'] ?? [];
if (empty($data)) {
Log::error("No data returned from API", ['url' => $url, 'uuid' => $uuid]);
return false;
}
$detailCreatedAt = isset($data['created_at'])
? Carbon::parse($data['created_at'])->format('Y-m-d H:i:s')
: null;
$detailUpdatedAt = isset($data['updated_at'])
? Carbon::parse($data['updated_at'])->format('Y-m-d H:i:s')
: null;
$pbg_task_retributions = PbgTaskRetributions::updateOrCreate(
['detail_id' => $data['id']],
[
'detail_uid' => $data['uid'] ?? null,
'detail_created_at' => $detailCreatedAt ?? null,
'detail_updated_at' => $detailUpdatedAt ?? null,
'luas_bangunan' => $data['luas_bangunan'] ?? null,
'indeks_lokalitas' => $data['indeks_lokalitas'] ?? null,
'wilayah_shst' => $data['wilayah_shst'] ?? null,
'kegiatan_id' => $data['kegiatan']['id'] ?? null,
'kegiatan_name' => $data['kegiatan']['name'] ?? null,
'nilai_shst' => $data['nilai_shst'] ?? null,
'indeks_terintegrasi' => $data['indeks_terintegrasi'] ?? null,
'indeks_bg_terbangun' => $data['indeks_bg_terbangun'] ?? null,
'nilai_retribusi_bangunan' => $data['nilai_retribusi_bangunan'] ?? null,
'nilai_prasarana' => $data['nilai_prasarana'] ?? null,
'created_by' => $data['created_by'] ?? null,
'pbg_document' => $data['pbg_document'] ?? null,
'underpayment' => $data['underpayment'] ?? null,
'skrd_amount' => $data['skrd_amount'] ?? null,
'pbg_task_uid' => $uuid,
]
);
$pbg_task_retribution_id = $pbg_task_retributions->id;
$prasaranaData = $data['prasarana'] ?? [];
if (!empty($prasaranaData)) {
$insertData = array_map(fn($item) => [
'pbg_task_uid' => $uuid,
'pbg_task_retribution_id' => $pbg_task_retribution_id,
'prasarana_id' => $item['id'] ?? null,
'prasarana_type' => $item['prasarana_type'] ?? null,
'building_type' => $item['building_type'] ?? null,
'total' => $item['total'] ?? null,
'quantity' => $item['quantity'] ?? null,
'unit' => $item['unit'] ?? null,
'index_prasarana' => $item['index_prasarana'] ?? null,
], $prasaranaData);
// Use bulk insert or upsert for faster database operation
PbgTaskPrasarana::upsert($insertData, ['prasarana_id']);
}
return true;
}catch(Exception $e){
Log::error("Failed to sync task detail submit", ['error' => $e->getMessage(), 'uuid' => $uuid]);
throw $e;
}
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class CustomCircle extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.custom-circle');
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class ModalConfirmation extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.modal-confirmation');
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\View\Components;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class ToastNotification extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.toast-notification');
}
}

View File

@@ -3,10 +3,14 @@
"name": "laravel/laravel", "name": "laravel/laravel",
"type": "project", "type": "project",
"description": "The skeleton application for the Laravel framework.", "description": "The skeleton application for the Laravel framework.",
"keywords": ["laravel", "framework"], "keywords": [
"laravel",
"framework"
],
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.2", "php": "^8.2",
"google/apiclient": "^2.12",
"guzzlehttp/guzzle": "^7.9", "guzzlehttp/guzzle": "^7.9",
"laravel/framework": "^11.31", "laravel/framework": "^11.31",
"laravel/sanctum": "^4.0", "laravel/sanctum": "^4.0",
@@ -15,7 +19,6 @@
}, },
"require-dev": { "require-dev": {
"fakerphp/faker": "^1.23", "fakerphp/faker": "^1.23",
"ibex/crud-generator": "^2.1",
"laravel/pail": "^1.1", "laravel/pail": "^1.1",
"laravel/pint": "^1.13", "laravel/pint": "^1.13",
"laravel/sail": "^1.26", "laravel/sail": "^1.26",

1381
composer.lock generated Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -123,4 +123,5 @@ return [
'store' => env('APP_MAINTENANCE_STORE', 'database'), 'store' => env('APP_MAINTENANCE_STORE', 'database'),
], ],
'api_url' => env('API_URL', 'http://localhost:8000')
]; ];

View File

@@ -0,0 +1,52 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| CodeGenerator config overrides
|--------------------------------------------------------------------------
|
| It is a good idea to separate your configuration form the code-generator's
| own configuration. This way you won't lose any settings/preference
| you have when upgrading to a new version of the package.
|
| Additionally, you will always know any the configuration difference between
| the default config than your own.
|
| To override the setting that is found in the 'config/default.php' file, you'll
| need to create identical key here with a different value
|
| IMPORTANT: When overriding an option that is an array, the configurations
| are merged together using php's array_merge() function. This means that
| any option that you list here will take presence during a conflict in keys.
|
| EXAMPLE: The following addition to this file, will add another entry in
| the common_definitions collection
|
| 'common_definitions' =>
| [
| [
| 'match' => '*_at',
| 'set' => [
| 'css-class' => 'datetime-picker',
| ],
| ],
| ],
|
*/
/*
|--------------------------------------------------------------------------
| The default path of where the uploaded files live.
|--------------------------------------------------------------------------
|
| You can use Laravel Storage filesystem. By default, the code-generator
| uses the default file system.
| For more info about Laravel's file system visit
| https://laravel.com/docs/5.5/filesystem
|
*/
'files_upload_path' => 'uploads',
];

View File

@@ -109,4 +109,10 @@ return [
'table' => 'failed_jobs', 'table' => 'failed_jobs',
], ],
// set timeout queue
'worker' => [
'timeout' => 300
]
]; ];

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
<?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('data_settings', function (Blueprint $table) {
$table->id();
$table->string('key')->unique();
$table->string('value');
$table->string('type')->nullable()->default('integer');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('data_settings');
}
};

View File

@@ -0,0 +1,80 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pbg_task_google_sheet', function (Blueprint $table) {
$table->id();
$table->string('jenis_konsultasi')->nullable();
$table->string('no_registrasi')->nullable()->unique();
$table->string('nama_pemilik')->nullable();
$table->text('lokasi_bg')->nullable();
$table->string('fungsi_bg')->nullable();
$table->string('nama_bangunan')->nullable();
$table->date('tgl_permohonan')->nullable();
$table->string('status_verifikasi')->nullable();
$table->string('status_permohonan')->nullable();
$table->text('alamat_pemilik')->nullable();
$table->string('no_hp')->nullable();
$table->string('email')->nullable();
$table->date('tanggal_catatan')->nullable();
$table->text('catatan_kekurangan_dokumen')->nullable();
$table->string('gambar')->nullable();
$table->string('krk_kkpr')->nullable();
$table->string('no_krk')->nullable();
$table->string('lh')->nullable();
$table->string('ska')->nullable();
$table->text('keterangan')->nullable();
$table->string('helpdesk')->nullable();
$table->string('pj')->nullable();
$table->string('kepemilikan')->nullable();
$table->string('potensi_taru')->nullable();
$table->string('validasi_dinas')->nullable();
$table->string('kategori_retribusi')->nullable();
$table->string('no_urut_ba_tpt')->nullable();
$table->date('tanggal_ba_tpt')->nullable();
$table->string('no_urut_ba_tpa')->nullable();
$table->date('tanggal_ba_tpa')->nullable();
$table->string('no_urut_skrd')->nullable();
$table->date('tanggal_skrd')->nullable();
$table->string('ptsp')->nullable();
$table->string('selesai_terbit')->nullable();
$table->date('tanggal_pembayaran')->nullable();
$table->string('format_sts')->nullable();
$table->integer('tahun_terbit')->nullable();
$table->integer('tahun_berjalan')->nullable();
$table->string('kelurahan')->nullable();
$table->string('kecamatan')->nullable();
$table->decimal('lb', 20,2)->nullable();
$table->decimal('tb', 20, 2)->nullable();
$table->integer('jlb')->nullable();
$table->integer('unit')->nullable();
$table->integer('usulan_retribusi')->nullable();
$table->decimal('nilai_retribusi_keseluruhan_simbg', 20, 2)->nullable();
$table->decimal('nilai_retribusi_keseluruhan_pad', 20, 2)->nullable();
$table->decimal('denda', 20, 2)->nullable();
$table->string('latitude')->nullable();
$table->string('longitude')->nullable();
$table->string('nik_nib')->nullable();
$table->string('dok_tanah')->nullable();
$table->text('temuan')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pbg_task_google_sheet');
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pbg_task', function (Blueprint $table) {
$constraintExists = DB::select("
SELECT COUNT(*) as count
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'pbg_task'
AND index_name = 'pbg_task_uuid_unique'
");
if ($constraintExists[0]->count > 0) {
$table->dropUnique('pbg_task_uuid_unique');
}
$table->string('uuid')->nullable()->unique()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pbg_task', function (Blueprint $table) {
$table->dropUnique('pbg_task_uuid_unique');
$table->string('uuid')->nullable()->change();
});
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pbg_task_index_integrations', function (Blueprint $table) {
$constraintExists = DB::select("
SELECT COUNT(*) as count
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'pbg_task_index_integrations'
AND index_name = 'pbg_task_index_integrations_pbg_task_uid_unique'
");
if ($constraintExists[0]->count > 0) {
$table->dropUnique('pbg_task_index_integrations_pbg_task_uid_unique');
}
$table->string('pbg_task_uid')->unique()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pbg_task_index_integrations', function (Blueprint $table) {
$table->dropUnique('pbg_task_index_integrations_pbg_task_uid_unique');
$table->string('pbg_task_uid')->unique()->change();
});
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pbg_task_retributions', function (Blueprint $table) {
$constraintExists = DB::select("
SELECT COUNT(*) as count
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'pbg_task_retributions'
AND index_name = 'pbg_task_retributions_detail_id_unique'
");
if ($constraintExists[0]->count > 0) {
$table->dropUnique('pbg_task_retributions_detail_id_unique');
}
$table->string('detail_id')->unique()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pbg_task_retributions', function (Blueprint $table) {
$table->dropUnique('pbg_task_retributions_detail_id_unique');
$table->string('detail_id')->unique()->change();
});
}
};

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
$constraintExists = DB::select("
SELECT COUNT(*) as count
FROM information_schema.statistics
WHERE table_schema = DATABASE()
AND table_name = 'pbg_task_prasarana'
AND index_name = 'pbg_task_prasarana_prasarana_id_unique'
");
if ($constraintExists[0]->count > 0) {
$table->dropUnique('pbg_task_prasarana_prasarana_id_unique');
}
$table->integer('prasarana_id')->nullable()->unique()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
$table->dropUnique('pbg_task_prasarana_prasarana_id_unique');
$table->integer('prasarana_id')->nullable()->unique()->change();
});
}
};

View File

@@ -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('pbg_task_prasarana', function (Blueprint $table) {
$table->unsignedBigInteger('pbg_task_retribution_id')->nullable(); // nullable in case some records do not match
// Step 2: Define the foreign key relation from `table3` to `table2`
$table->foreign('pbg_task_retribution_id')->references('id')->on('pbg_task_retributions')->onDelete('cascade');
});
\DB::table('pbg_task_prasarana')
->join('pbg_task', 'pbg_task.uuid', '=', 'pbg_task_prasarana.pbg_task_uid') // Relating pbg_task_prasarana to pbg_task
->join('pbg_task_retributions', 'pbg_task_retributions.pbg_task_uid', '=', 'pbg_task.uuid') // Relating pbg_task_retributions to pbg_task
->whereNotNull('pbg_task_retributions.id') // Ensure the `pbg_task_retributions` id exists
->update(['pbg_task_prasarana.pbg_task_retribution_id' => \DB::raw('pbg_task_retributions.id')]); // Set the foreign key
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('pbg_task_prasarana', function (Blueprint $table) {
$table->dropForeign(['pbg_task_retribution_id']);
$table->dropColumn('pbg_task_retribution_id');
});
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('roles');
}
};

View File

@@ -0,0 +1,33 @@
<?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('menus', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('url');
$table->string('icon')->nullable();
$table->unsignedBigInteger('parent_id')->nullable();
$table->integer('sort_order')->default(0);
$table->foreign('parent_id')->references('id')->on('menus')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('menus');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_role', function (Blueprint $table) {
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('role_id')->constrained()->onDelete('cascade');
$table->primary(['user_id', 'role_id']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_role');
}
};

Some files were not shown because too many files have changed in this diff Show More