Compare commits
215 Commits
feature/re
...
feat/recre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59cc102c5a | ||
|
|
df70a47bd1 | ||
|
|
e71dd7d213 | ||
|
|
f2eb998ac5 | ||
|
|
fc54e20fa4 | ||
|
|
6946fa7074 | ||
|
|
236b6f9bfc | ||
|
|
285ff46c2b | ||
|
|
a8b02afad9 | ||
|
|
a0666e78d2 | ||
|
|
799e409ce2 | ||
|
|
780ba60224 | ||
|
|
baed8cc487 | ||
|
|
e17f5beaf0 | ||
|
|
766e1a430c | ||
|
|
6677c320fc | ||
|
|
9437eb949f | ||
|
|
6f77120c33 | ||
|
|
f8d0573e5c | ||
|
|
ca74d0143f | ||
|
|
34e082c31b | ||
|
|
c4d865bf2b | ||
|
|
a103b38265 | ||
|
|
9aa3d32b6e | ||
|
|
99e2c214b6 | ||
|
|
501a76bc81 | ||
|
|
460267992e | ||
|
|
becc368069 | ||
|
|
2618ac06d0 | ||
|
|
d95676d477 | ||
|
|
7737fee30f | ||
|
|
48293386c7 | ||
|
|
84870b95b1 | ||
|
|
6294d2f950 | ||
|
|
7b70591be5 | ||
|
|
3b67bfd1fb | ||
|
|
45e22096ed | ||
|
|
c7a8d6d249 | ||
|
|
091b1f305e | ||
|
|
e7950e22f2 | ||
|
|
b68641db03 | ||
|
|
fefb85ac7a | ||
|
|
d28a08a24c | ||
|
|
654d2efe19 | ||
|
|
0a080763cd | ||
|
|
f3ef21d1be | ||
|
|
d7bff86741 | ||
|
|
f36f250700 | ||
|
|
2c5da87856 | ||
|
|
a195559c4b | ||
|
|
088f173fec | ||
|
|
eadfddb3a4 | ||
|
|
47a9fb1dfb | ||
|
|
1713e32b67 | ||
|
|
cf998455e0 | ||
|
|
5e1c9f3a2e | ||
|
|
e940b8d6c7 | ||
|
|
5e139bc29c | ||
|
|
f9e1aa1604 | ||
|
|
2e385f80cd | ||
|
|
e2c26e0eff | ||
|
|
ca5b8ad403 | ||
|
|
e97b7eb70d | ||
|
|
0258ca9f04 | ||
|
|
0116147e06 | ||
|
|
7787db02a3 | ||
|
|
e47ab36d5e | ||
|
|
e5db2294b4 | ||
|
|
4db457d7bd | ||
|
|
7a82ad5302 | ||
|
|
b0d4d4c23b | ||
|
|
68ffc1c090 | ||
|
|
a1f4bd7f81 | ||
|
|
238aaba96c | ||
|
|
c7152d9dbe | ||
|
|
2a4b96d0b2 | ||
|
|
dd940ebdb6 | ||
|
|
dce5409248 | ||
|
|
b8f7d7f655 | ||
|
|
65600f1b4f | ||
|
|
b0f15a9221 | ||
|
|
bf55eb228e | ||
|
|
755720bac9 | ||
|
|
098b4c605b | ||
|
|
4632e102eb | ||
|
|
0431945a42 | ||
|
|
fbfa2a37bb | ||
|
|
c529a5d511 | ||
|
|
ff244039ff | ||
|
|
55902042f4 | ||
|
|
c67aa979c2 | ||
|
|
fbaa33ae13 | ||
|
|
9516b6f575 | ||
|
|
ffc08f26cc | ||
|
|
dceb46ab86 | ||
|
|
e0c35b8897 | ||
|
|
22ee7502ad | ||
|
|
2f3bc172eb | ||
|
|
bba932b2ba | ||
|
|
3f5d0eb1cd | ||
|
|
1f33d0de4e | ||
|
|
86d694bcac | ||
|
|
cb5a3243fc | ||
|
|
15210a56ee | ||
|
|
a08f2cb2b7 | ||
|
|
632433c496 | ||
|
|
5b4780495e | ||
|
|
0a7012a57c | ||
|
|
435a19346b | ||
|
|
8fcf8859d6 | ||
|
|
43a246d234 | ||
|
|
d6d0acf8fb | ||
|
|
b4ec7a9d25 | ||
|
|
5203babe11 | ||
|
|
c0faafdbd7 | ||
|
|
c5e3fdd915 | ||
|
|
572b86299c | ||
|
|
cdd84d02da | ||
|
|
ee1a395c75 | ||
|
|
3bfcaddba4 | ||
|
|
9ea7e96af1 | ||
|
|
e0d11af7d2 | ||
|
|
fefef609ac | ||
|
|
f5790cda94 | ||
|
|
f3db3783f9 | ||
|
|
101e76c0fa | ||
|
|
4cc698a623 | ||
|
|
544ad1db46 | ||
|
|
30ca819aa1 | ||
|
|
b0bab784d1 | ||
|
|
01fda22c89 | ||
|
|
de300c2c32 | ||
|
|
7f8a2e4936 | ||
|
|
38948b6633 | ||
|
|
aa9943ba45 | ||
|
|
9e55ea0dbb | ||
|
|
93f0ac5ef7 | ||
|
|
8bae33519f | ||
|
|
6865e353e6 | ||
|
|
bb4ab5c769 | ||
|
|
e743b82087 | ||
|
|
c3c7b8e3ec | ||
|
|
d49035ce8d | ||
|
|
ffd9d3514c | ||
|
|
675477c734 | ||
|
|
4350c466e3 | ||
|
|
5ab407d672 | ||
|
|
2aaa487746 | ||
|
|
080582f7ab | ||
|
|
91475aeead | ||
|
|
a7afbd69fb | ||
|
|
1ff5587050 | ||
|
|
9c8a1a3f3f | ||
|
|
5c4be7635b | ||
|
|
ba315b1dee | ||
|
|
33b7131c33 | ||
|
|
7a56735099 | ||
|
|
dd331b4a08 | ||
|
|
dcd93d66e2 | ||
|
|
5d50d6d6cc | ||
|
|
39717d184c | ||
|
|
54146c8c08 | ||
|
|
e8da7193ef | ||
|
|
006c008542 | ||
|
|
39bb8e6d5f | ||
|
|
7994a62cea | ||
|
|
3a09e2e68a | ||
|
|
116dc1c8c7 | ||
|
|
f10bc153b4 | ||
|
|
06a3bb8c8b | ||
|
|
6c936d4c14 | ||
|
|
d4d0a485cd | ||
|
|
864fb26471 | ||
|
|
fd97a34344 | ||
|
|
1dd971fb73 | ||
|
|
aff31e08ef | ||
|
|
2fb8aeceaa | ||
|
|
ecc243d1cc | ||
|
|
beac71d182 | ||
|
|
8c236c460d | ||
|
|
154b7f40df | ||
|
|
59e9431b2d | ||
|
|
074edc607d | ||
|
|
625d182d81 | ||
|
|
4d32d4a110 | ||
|
|
ac2f37d549 | ||
|
|
a9afb47f08 | ||
|
|
9efb6c346e | ||
|
|
6ba62da5ca | ||
|
|
ba95c185de | ||
|
|
41ddbaef24 | ||
|
|
b4b34b503e | ||
|
|
1a15bc03f8 | ||
|
|
2bf4b8b327 | ||
|
|
cb90f69d1e | ||
|
|
6307417ae3 | ||
|
|
55dc0751d3 | ||
|
|
97ffd322a1 | ||
|
|
6fb59e58e9 | ||
|
|
7e99d547c8 | ||
|
|
65f82c9bfd | ||
|
|
44ebc20d3c | ||
|
|
b60bbd4290 | ||
|
|
29b705b59c | ||
|
|
95ab8eff7f | ||
|
|
bfc2f7f1f9 | ||
|
|
50f1757a64 | ||
|
|
d54edb7783 | ||
|
|
3309664bae | ||
|
|
4eac6ab83d | ||
|
|
604e0d8479 | ||
|
|
99e99fa2e6 | ||
|
|
ff324014f6 | ||
|
|
7d06e12de8 | ||
|
|
f38d518f96 |
0
.editorconfig
Executable file → Normal file
0
.editorconfig
Executable file → Normal file
7
.env.example
Executable file → Normal file
7
.env.example
Executable file → Normal 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,6 @@ 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"
|
OPENAI_API_KEY="xxxxx"
|
||||||
76
.env.local.backup
Normal file
76
.env.local.backup
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
APP_NAME=SIBEDAS-PBG
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=base64:xqCpwixWKqgu1Ca22gFizoOt44p7h+cgTOKuhS/P0Jw=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_TIMEZONE=Asia/Jakarta
|
||||||
|
APP_URL=http://localhost:8000
|
||||||
|
|
||||||
|
API_URL=http://localhost:8000
|
||||||
|
|
||||||
|
APP_LOCALE=en
|
||||||
|
APP_FALLBACK_LOCALE=en
|
||||||
|
APP_FAKER_LOCALE=en_US
|
||||||
|
|
||||||
|
APP_MAINTENANCE_DRIVER=file
|
||||||
|
# APP_MAINTENANCE_STORE=database
|
||||||
|
|
||||||
|
PHP_CLI_SERVER_WORKERS=4
|
||||||
|
|
||||||
|
BCRYPT_ROUNDS=12
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_STACK=single
|
||||||
|
LOG_DEPRECATIONS_CHANNEL=null
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
DB_CONNECTION=mariadb
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=sibedas_db
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=root
|
||||||
|
|
||||||
|
SESSION_DRIVER=database
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
SESSION_ENCRYPT=false
|
||||||
|
SESSION_PATH=/
|
||||||
|
SESSION_DOMAIN=null
|
||||||
|
|
||||||
|
BROADCAST_CONNECTION=log
|
||||||
|
FILESYSTEM_DISK=local
|
||||||
|
QUEUE_CONNECTION=database
|
||||||
|
|
||||||
|
CACHE_STORE=database
|
||||||
|
CACHE_PREFIX=
|
||||||
|
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
|
REDIS_CLIENT=phpredis
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_MAILER=log
|
||||||
|
MAIL_HOST=127.0.0.1
|
||||||
|
MAIL_PORT=2525
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
SIMBG_HOST="https://simbg.pu.go.id/"
|
||||||
|
SIMBG_EMAIL="dputr@bandungkab.go.id"
|
||||||
|
SIMBG_PASSWORD="Simbg123"
|
||||||
|
|
||||||
|
API_KEY_GOOGLE="AIzaSyBxfEShFkKmykkc7RJR3lVzkQ_xGHK3qr0"
|
||||||
|
SPREAD_SHEET_ID="1QoXzuLdEX3MK70Yrfigz0Qj5rAt4T819jX85vubBNdY"
|
||||||
|
OPENAI_API_KEY="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"
|
||||||
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
42
Data_2025___Estimasi_Jumlah_Lantai.csv
Executable file
42
Data_2025___Estimasi_Jumlah_Lantai.csv
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
no,pemohon,alamat,activities,luas_lahan,bcr_kawasan,area,no_tapak,no_skkl,no_ukl,fungsi_bangunan,sub_fungsi_bangunan,jumlah_lantai
|
||||||
|
01/222,PT CIPTA INDAH PERTIWI No Telpon : 082217633434,Jl Salam No 51 Desa/Kel. Cihapit Kec. Bandung wetan Kota Bandung,PERUMAHAN LA LA TOWN,16629,0.2449,4072.4421,648.11./222 - SP /TR 07 Januari 2025;644.2./207 - SP /TR 02 Januari 2025,500.10.29.15/631-REKTEK/TR Tanggal 14 Februari 2023;500.10.29.15/2837-REKTEK/Bid. Taru Tanggal 25 Juli 2024,14022310313204030 Tanggal 14 Februari 2023;500.10.29.7/Kep.618-DLH/2024 Tanggal 13 Desember 2024;161023087545 Tanggal 16 Oktober2023,Fungsi Hunian,Fungsi Hunian,1
|
||||||
|
03/481,MUHAMAD GUNTUR JULIADI No Telpon : 081223334486,Cangkuang Residence RT 004/003 Ds Cangkuang Wetan Kec. Dayeuhkolot Kab. Bandung,PERUMAHAN CANGKUANG RESIDENCE 2,2360,0.5924,1398.064,648.11./481 - SP /TR 15 Januari 2025;647./226 - SP /TR 07 Januari 2025;647/225 - SP /TR 07 Januari 2025;644/221 - SP /TR 07 Januari 2025;645.4/557 - SP /TR 20 Januari 2025,500.10.29.15/2894-REKTEK/Bid. Taru Tanggal 08 Agustus 2024;400.7.22/4927-KRK/04/Bid.Taru Tanggal 06 Desember 2024;500.10.29.15/2619-REKTEK/Bid. Taru Tanggal 10 Juli 2024;500.10.29.15/4155-REKTEK/Bid. Taru Tanggal 18 Nopember 2024;503/123/III-DPMPTSP/2020 Tanggal 24 MAret 2020,167240099471 Tanggal 16 Juli 2024;9120111161314 Tanggal 11 Nopember 2019;8120312190151 Tanggal 04 Desember 2023;500.10.29.7/Kep.614-DLH/2024 Tanggal 20 Nopember 2024;2910240290118 Tanggal 29 Oktober 2024;8120001992981 Tanggal 12 Juli 2024;SK.294/Menlhk/Setjen/PLA.4/5/2021 Tanggal 31 Mei 2021,Fungsi Hunian,Fungsi Hunian,1
|
||||||
|
08/480,PT SURYA KHARISMA PARAHYANGAN No Telpon : 081394461006 ,Jalan Cibaligo No 48 Desa /Kel. Cigugur tengah Kec. Cimahi tengah kota Cimahi ,PERUMAHAN PARAHYANGAN GARDEN CITY,116360,0.5164,60088.304,648.11./480 - SP /TR 15 Januari 2025,500.10.29.15/603-REKTEK/TR Tanggal 05 Desember 2023,1810220245722 Tanggal 18 Oktober 2022;500.10.29.7/Kep.632-DLH/2024 Tanggal 24 Desember 2024,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
09/223,PT CLARICHEM INDONESIA No Telpon : 081315399694,Kawasan pergudangan taman tekno sektor XI blok L2 No 30 Ds/Kel. Setu Kec. Setu kota Tangerag Banten ,PERGUDANGAN DAN PENYIMPANAN,1586,0.7017,1112.8962,644./223 - SP /TR 07 Januari 2025,400.7.22/4427-KRK/03/Bid.Taru Tanggal 06 Desember 2024,9120008832767 Tanggal 26 Nopember 2024,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
10/657,PT HALKA GITA No Telpon : 0816734374,Jl Raya Majalaya KM 2 RT 02/09 Desa Hegarmanah Kec. Cikancung Kab. Bandung,REVISI 1 KOMPLEK PERGUDANGAN,19100,0.699,13350.9,644./657 - SP /TR 23 Januari 2025,500.10.29.15/6750-REKTEK/TR Tanggal 21 Desember 2023,9120300510839 Tanggal 16 Desember 2023;500.10.29.7/Kep.609-DLH/2024 Tanggal 12 Nopember 2024,Usaha Besar (Non-Mikro),Fungsi Usaha,2
|
||||||
|
11/658,PT SURYA TIRTA KENCANA No Telpon : 08986155493,Kutawaringin Industrial Park Kav. 276-277 Desa Jelegong Kec. Kutawaringin Kab. Bandung,PERGUDANGAN DAN PENYIMPANAN BAHAN KIMIA,3932,0.6995,2750.434,644./658 - SP /TR 23 Januari 2025;640/540 - SP /TR 20 Januari 2025,10112410113204010 Tanggal 10 Nopember 2024;591.4/031/IX-DPMPTSP/2020 Tanggal 03 Sseptember 2020,8120017120594 Tanggal 31 Agustus 2018;600.4.5/056/6838-Ktr/TL Tanggal 24 Desember 2024;0220305221438 Tanggal 20 Nopember 2021;500.10.29.7/4295/TL Tanggal 21 September 2024,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
13 / 550,PT BERKAH SEPUH JAYA No Telpon : 082118781624,Ruko komplek dewaadru blok R3 RT 005 ds/kec. Bojongsoang kab. Bandung,REVISI 1 PERUMAHAN VILLA CEMARA ASRI,17379,0.5476,9516.7404,648.11/550 - SP/TR 20 Januari 2025,150223101113204049 Tanggal 15 Februari 2023,1233000451657 Tanggal 5 Mei 2023;500.10.29.7/kep.392-DLH/2025 Tgl. 2 Januari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
14 / 655,PT RISKI ANUGERAH SEDJAHTERA No Telpon : 082118781624,Griya permata asri blok C2 No 18 Ds Lengkong Kec. Bojongsoang Kab. Bandung,REVISI 1 PERUMAHAN TAMAN KATAPANG INDAH,28425,0.6532,18567.21,648.11 /655 - SP /TR 23 Januari 2025,500.10.29.15/2333-REKTEK/TR Tanggal 22 Mei 2024;500.10.29.15/3811-REKTEK/Bid. Taru Tanggal 10 Oktober 2024,1205000302875 Tanggal 02 April 2024;500.10.29.7/Kep.408-DLH/2025 Tanggal 10 Januari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
15 / 551,PT BUMI SUWARNA SEJAHTERA No Telpon : 082118781624,Jl Ciwastra no 73 Kel. Mekarmulya kec. Rancasari kota bandung,REVISI 1 PERUMAHAN BUMI KARA RESIDENCE,29711,0.5424,16115.2464,648.11/551-SP/TR 20 Januari 2025,500.10.29.15/6097-REKTEK/TR Tanggal 27 Nopember 2023,1311230078306 Tgl 13 Nopember 2023;500.10.29.7/Kep.493-DLH/2024 Tanggal 20 Maret 2024,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
16 / 656,PT AMBER HASYA No Telpon : 081312411661,Jl Sarijadi raya No 111 Kel. Sarijadi Kec. Sukasarii kota bandung,REVISI 1 PERUMAHAN GREEN HARMONI RESIDENCE ,39520,0.2726,10773.152,648.11/656-SP/TR 23 Januari 2025,500.10.29.15/2732-REKTEK/Bid. Taru Tanggal 19 Juli 2024,9120004882226 Tgl 22 Agustus 2019;500.10.29.7/Kep.617-DLH/2024 Tanggal 4 Desember 2024,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
17 / 224,PT KARYA UTAMA SEJATI JAYA No Telpon : 081320772222,Kp. Andir DS/Kel. Manggahang Kec. Baleendah Kab. Bandung,PERUMAHAN GRAND CIPARAY RESIDENCE,12045,0.5945,7160.7525,648.11/224-SP/TR 07 Januari 2025;644/822-SP/TR 13 Februari 2025;640/524-SP/TR 17 Januari 2025;642/763-SP/TR 11 Februari 2025,500/5300-PERTEKTR/2022/TR Tanggal 04 Agustus 2022;400.7.22/4872-KRK/25/Bid.TR Tanggal 24 Desember 2024;Pu.650/7580-REKTEK/TR Tanggal 20 Desember 2022;01112410113204120 Tanggal 1 November 2024,1801220061544 Tgl 05 September 2022;600.4.5/052/1722-Ktr/TL Tanggal 20 Mei 2024;9120401971173 Tgl 11 Desember 2024;1406220076826 Tgl 15 November 2022;8120103802893 Tgl 29 Agustus 2018,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
21 / 688,PT PRAKARSA FAJAR PROPERTINDO No Telpon : 082315094712,Jl. Otto Iskandardinata No 429 Kel. Pungkur Kec. Regol Kota Bandung,PERUMAHAN ALAM BUMI CIPARAY,17417,0.6793,11831.3681,648.11/688-SP/TR 03 Februari 2025,500.10.29.15/1075-REKTEK/TR Tanggal 04 Maret 2024,9120007841259 Tgl 15 Agustus 2019;500.10.29.7/Kep.405-DLH/2025 Tanggal 06 Januari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
22 / 767,PT CITRA SENTOSA JAYATAMA No Telpon : 087825393706,Jl. Nyengseret No 29 RT 01 Kel. Pelindung hewaqn Kota Bandung,PERUMAHAN CITRA ASRI RESIDENCE,28900,0.692,19998.8,648.11/767-SP/TR 12 Februari 2025,500.10.29.15/2617-REKTEK/Bid. Taru Tanggal 10 Juli 2024,9120107971097 Tgl 19 September 2019;500.10.29.7/Kep.612-DLH/2024 Tanggal 18 November 2024,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
23/ 641,PT PESONA MITRA KEMBAR MAS No Telpon : 081220763283,Jl Kembar mas IV No 2A RT 05/09 Kel. Pasirluyu Kec. Regol Kota Bandung,REVISI 5 PERUMAHAN PODOMORO PARK,1160011,0.6691,776163.3601,648.11/641- SP/TR 22 Januari 2025,591/057-DPMPTSP/2017 Tanggal 28 Desember 2017,650/Kep.628-DLH/2018 Tanggal 30 Nopember 2018,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
24 / 659,PT PAVITRA PARA ARTHA No Telpon : 081809063866,Jl . Kubang Beureum No 39 RT 007 / 011 Kelurahan Sekejati Kecamatan Buahbatu,REVISI 4 PERUMAHAN PRIVATE VILLAGE,88245,0.5819,51349.7655,648.11/659 - SP/TR 23 Januari 2025;645/932 - SP/TR 21 Februari 2025;645/552-SP/TR 20 Januari 2025;647/640-SP/TR 22 Januari 2025;647/930-SP/TR 21 Februari 2025,591.4/001-BPMP/2014 Tanggal 06 Januari 2014;591.4/031-DPMPTSP/2019 Tanggal 10 Juli 2019;503/104/XII-DPMPTSP/2019- Tgl 20 Desember 2019;400.1.22/4521-KRK/15/Bid.Taru Tgl 16 Desember 2024;650/2597-KRTR/2021/TR Tgl 9 Desember 2021;500.10.29.15/2839-REKTEK/Bid.TAru Tgl 2 Agustus 2024,500.10.29.6/4898/TL Tanggal 08 Nopember 2023;667/2995/TL Tanggal 11 Agustus 2020;9120000431996 Tanggal 20 Oktober 2021;500.10.29.7/Kep.629-DLH/2024;9120605793306 Tanggal 9 Mei 2023;1601240112040181 Tanggal 16 Januari 2024;8120215192631 Tanggal 3 Januari 2022;34/LH.01.06.05/DLH Tanggal 3 Januari 2025;9120101841825 Tanggal 18 Oktober 2023,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
29 / 931,PT KARYA HAFANA INTAN MANDIRI No Telpon : 082120002925 ,Kp./Desa Ciluluk Kecamatan Cikancung Kabupaten Bandung,PERUMAHAN GRIYA CIHANYIR PERMAI,24432.33,0.5945,14525.02019,648.11/931 - SP/TR 21 Februari 2025,400.7.22/4840-KRK/21/Bid.Taru Tgl. 18 Desember 2024,2908210007625 Tanggal 06 Mei 2024;500.10.29.7/Kep.414-DLH/2025 Tanggal 30 Januari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
30 / 933,PT ARUM JAYA PROPERTI No Telpon : 085100942672,Perumahan Banyu Arum Residence Blok A Kp. Tegal Tengah RT 003/013 Desa Cangkuang Kec. Rancaekek,REVISI 1 PERUMAHAN BUMI ARUM REGENCY,58899,0.4838,28495.3362,648.11/933 - SP/PR 21 FEBRUARI 2025,591.4/026-DPMPTSP/2018 Tgl 24 September 2018,667/7210/TL Tanggal 16 Nopember 2018;500.10.29.6/Kep.420-DLH/2025 Tanmggal 3 Februari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
31 / 762,SANDY SALMAN No Telpon : 082118781624,Jl Kembar VIII No 26 RT 005/010 Kel Cigereleng Kec. Regol Kota Bandung 40253,REVISI 1 PERUMAHAN D HEUVEL WIWAHA PADASUKA,3095,0.4295,1329.3025,648.11/ 762 - SP / PR 11 Februari 2025;648/523-SP/TR 17 Januari 2025;647/1140-SP/TR 27 Februari 2025;647/934-SP/TR 21 Februari 2025;647/1233-SP/TR 06 Maret 2025,"650/5689-PETEKTR/2022/TR Tanggal 30 Agustus 2022;650/2748-KRTR/2021/TR Tgl 21 Desember 2021;593.SK.93-BKPMD/90 Tanggal 11 April 1990;593/SK.225-BKPMD/1991 Tanggal 28 Juni 1991;591,4/009-BPMP/2014 Tanggal 27 Maret 2014;500.10.29.15/711-REKTEK/TR Tanggal 15 Februari 2024;500.10.29.15/2877-REKTEK/Bid.Taru Tanggal 19 Agustus 2024 ",LH.01.04/5866-SPPL/TL Tanggal 27 Desember 2022;1402220064386 Tanggal 04 Februari 2022;500.10.29.7/Kep.593-DLH/2024 Tanggal 27 September 2024;667/3257/BPLH Tanggal 06 Oktober 2014;2711230388253 Tanggal 27 Nopember 2023;500.10.29.7/Kep.630-DLH/2024 Tanggal 20 Desember 2024;9120312050674 Tanggal 07 Oktober 2019;500.10.29.7/Kep.426-DLH/2025 Tanggal 14 Februari 2025,Fungsi Hunian,Fungsi Hunian,1
|
||||||
|
36/ 1141,HANDRIAWAN No Telpon : 081313350382,Jalan Taman Holis Indah E-5 No 4-5 RT 03/06 Ds/Kel. Cigondewah Kec. Bandung kulon. Kota Bandung,TOKO DAN GUDANG,2025,0.7848,1589.22,647/1141-SP/TR 27 Februari 2025;647/1211-SP/TR 04 Maret 2025;648.2/1091-SP/TR 25 Februari 2025,400.7.22/559-KRK/14/Bid.Taru Tanggal 17 Januari 2025;400.7.22/859-KRK/38/Bid.Taru Tanggal 17 Februari 2025;500.10.29.15/4064 - REKTEK/Bid.Taru Tanggal 25 Nopember 2024,1401250067962 Tanggal 14 Januari 2025;1812240057832 Tanggal 18 Desember 2024;1611210013009 Tanggal 16 Nopember 2021,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
39/ 1232,JOHANSJAH SUGIANTO No Telpon : 081314974495,Jalan Kepodang VI/6 blok k2 Rengas Kec. Ciputat timur kota Tangerang selatan,TOKO,2490,21.9,54531,644.2/1232-SP/TR 06 Maret 2025;644.2/1234-SP/TR 06 Maret 2025,400.7.22/1089 - KRK/45//Bid.Taru Tanggal 24 Februari 2025;503/0017-PKKPRNB/DPMPTSP/II/2025 Tanggal 12 Februari 2025,3101250002573 Tanggal 31 Januari 2025;2107230112343 Tanggal 21 Juli 2023,Tidak Diketahui,Tidak Diketahui,3
|
||||||
|
41 / 1090,TIM AD HOC PERUMAHAN SUKAWANGI RESIDENCE No Telpon : 08112255770,Kp. Cihalimun RT 02/04 Ds. Cibeureum Kec. Kertasari Kab. Bandung,PERUMAHAN SUKAWANGI RESIDENCE,,1,,648.11/ 1090 - SP / PR 25 Februari 2025,,,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
42 / 1298,PT TIGA REKAN INDONESIA No Telpon : 08122444717,Jl Gradiul No 40 RT 04/07 Kel. Rancaekek Kencana Kec. Rancaekek Kab. Bandung,PERUMAHAN GREEN HILL VILLAGE,16548,0.5917,9791.4516,648.11/1298 - SP/TR 17 Maret 2025,50.10.29.15/2742-REKTEK/Bid. Taru Tanggal 24 Juli 2024,2505240130006 Tanggal 25 Mei 2024;600.4.5/061/832-Ktr/Bid. TL/2025 Tgl. 19 Februari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
43 / 1322,PT UNILOA ARDIYANTO INVESTAMA No Telpon : 081220180480,Jl Raya Ebah 103 Desa Sukamantri Kecamatan Paseh Kab. Bandung,PERUMAHAN MARISON CIPAKU,19209,0.6146,11805.8514,648.11/1322 - SP/TR 18 Maret 2025,24042410313204051 Tanggal 24 JApril 2024,0238010110358 Tanggal 11 Januari 2024;500.10.29.7/Kep. 451-DLH/2025 Tgl. 13 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
44 / 1323,PT RADINAKA KRAMAT ABADI No Telpon : 082118781624,Jl. Sukamukti RT 01/06 Desa Sukamukti Kec. Katapang Kab. Bandung,PERUMAHAN GAHARU PALEDANG RESIDENCE,14665,0.68003,9972.63995,648.11/1323 - SP/TR 18 Maret 2025,02032510213204087 Tanggal 02 Maret 2025,0238010110358 Tanggal 11 Januari 2024;600.4.5/064/1165-Ktr/Bid. TL/2025 Tgl. 12 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
45 / 1361,PT SANGKURIANG KRAMAT ABADI No Telpon : 082118781624,Kampung rancakasiat Desa Rancamulya Kec. Pameungpeuk Kab. Bandung,PERUMAHAN PONDOK ASRI SUKAMUKTI,20451,0.6806,13918.9506,648.11/1361 - SP/TR 24 Maret 2025,500.10.29.15/3451-REKTEK/Bid.Taru Tanggal 26 September 2024,0811230037204 Tanggal 08 Nopember 2023;500.10.29.7/Kep.460-DLH/2025 Tgl. 21 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
46 / 1360,PT AUF ABDURACCHMAN JAYA No Telpon : 082118781624,Jl. Rancabungur rancakasiat Desa Malakasari Kec. Baleendah Kab. Bandung,PERUMAHAN BUMI SHANGRILA RESIDENCE,12846,0.6412,8236.8552,648.11/1360 - SP/TR 24 Maret 2025,400.7.22/093/1390-KRK/Bid.Taru Tanggal 17 Maret 2025,0603250028082 Tanggal 06 Maret 2025;600.4.5/072/1270-Ktr/Bid.TL/2025 Tgl. 21 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
47 / 1142,ANTO DWI HARTANTO No Telpon : 082126215611,Jl. Elang V No 8 RT 08/01 Kel. Garuda Kec. Andir Kota Bandung,PERGUDANGAN DAN PENYIMPANAN,1307,0.5616,734.0112,647/1142 - SP/TR 27 Februari 2025;648.11/823 - SP/TR 13 Februari 2025;644.2/1389 - SP/TR 26 Maret 2025;644.2/1388 - SP/TR 26 Maret 2025,500.10.29.15/3827-REKTEK/Bid.Taru Tanggal 17 Oktober 2024;500.10.29.15/3944-REKTEK/Bid.Taru Tanggal 28 Oktober 2024;503/0072-DPMPTSP/XI/2023 Tanggal 29 November 2023;400.7.22/1046-KRK/Bid.Taru Tanggal 21 Februari 2025,2009240075774 Tanggal 20 September 2024 2025;2009240075774 Tanggal 20 September 2025;500.10.29.7/Hep-461-DLH/2025 Tanggal 21 Maret 2025;0298000921888 Tanggal 24 Januari 2022,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
51 / 1161,PT INGRIA PRATAMA CAPITALINDO Tbk No Telpon : 087722361043,Ruko Pondok Cabe Mutiara Jl Pondok cabe No 27 Kel. Pamulang Kec. Pamulang Kota Tangerang Selatan,REVISI 2 PERUMAHAN BUKIT ESMA CICALENGKA 2 ,74300,0.6292,46749.56,648.11/1161 - SP/TR 28 Februari 2025,50.10.29.15/2927-REKTEK/Bid. Taru Tanggal 14 Agustus 2024,591.4/005/IX-DPMPTSP/2019 Tanggal 09 September 2019;500.10.29.7/Kep.613-DLH/2024 Tgl. 18 November 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
52 / 1441 ,PT ABADI MUKTI KIRANA No Telpon : 087821848944,Jl Terusan jamika No 88 Kel. Jamika Kec. Bojongloa kaler Kota Bandung, PERUMAHAN KOTA BARU ARJASARI,222816,1,222816,648.11/1441 - SP/TR 11 April 2025,400.7.28/1710/TR Tanggal 23 April 2024,9120108201236 Tanggal 13 Februari 2019;500.10.29.7/Kep.419-DLH/2025 Tgl. 03 Februari 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
53 / 1566,PT MAKMUR INDAH DAMAI No Telpon : 081394722234,Jl. Podomoro Boulevard utara I Desa Lengkong Kec. Bojongsoang Kab. Bandung,PERUMAHAN BAROS INDAH RESIDENCE,17513,1,17513,647/1566 - SP/TR 25 April 2025,50.10.29.15/2507-REKTEK/Bid. Taru Tanggal 25 Juni 2024,2106240023693 Tanggal 21 Juni 2024;500.10.29.7/Kep.447-DLH/2024 Tgl. 10 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
54 / 1343,PT KARYA BUMI BESTARI No Telpon : 08156080428,Kembar Mas IV No 2A RT 05/09 Kel. Pasirluyu Kec. Regol Kota Bandung,PERUMAHAN BESTARI MAS,26134,1,26134,648.11/1343 - SP/TR 20 Maret 2025;647/1565 - SP/TR 25 April 2025;648.1/1543 - SP/TR 17 April 2025,12042310213204004 Tanggal 12 April 2023;23122410113204057 Tanggal 23 Desember 2024;400.7.22/1047-KRK/42/Bid.Taru Tanggal 21 Februari 2025,1204230043635 Tanggal 12 April 2023;500.10.29.7/964/Bid. TL/2025 Tgl. 19 Februari 2025;9120304390956 Tanggal 05 Desember 2023;0307230050445 Tanggal 03 Juli 2023,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
57 / 1372,TENNI DIANA No Telpon : 082116106640,Cikaahuripan RT 002/005 Kec. Neglasari Kota Tangerang,PERADAGANGAN KHUSUS KARPET PERMADANI DAN PENUTUP DINDING DN LANTAI DI TOKO,1290,1,1290,644/1372 - SP/TR 26 Maret 2025;647/1557 - SP/TR 22 April 2025;640/1559 - SP/TR 22 April 2025;644/1371 - SP/TR 26 Maret 2025;644/1375 - SP/TR 26 Maret 2025;644/1373 - SP/TR 26 Maret 2025,500.10.29.15/4355-REKTEK/TR Tanggal 25 Agustus 2023;500.10.29.15/1073-REKTEK/TR Tanggal 04 Maret 2024;400.7.22/759-KRK/34/Bid.Taru Tanggal 11 Februari 2025;500.10.29.15/4654-REKTEK/Bid. Taru Tanggal 08 September 2023;500.10.29.15/4160-REKTEK/Bid. Taru Tanggal 15 Nopember 2024;500.10.29.15/2500-REKTEK/Bid. Taru Tanggal 19 Juni 2024,9120306652149 Tanggal 26 Juni 2019;0220107462528 Tanggal 08 September 2022;1283000240318 Tanggal 01 Februari 2021;600.4.5/071-KTR/Bid.TL/2025 Tgl. 05 Mei 2025;0220301251224 Tanggal 11 Agustus 2023;1263000210596 Tanggal 09 Februari 2021;1405240295325 5 Mei 2024,Tidak Diketahui,Tidak Diketahui,1
|
||||||
|
63 / 1567,Ir. BERSIH TARIGANT No Telpon : 081322777581,Jl Multatuli No 3 rt 001/001 Ds/Kel. Lebakgede Kec. Coblong Kota Bandung,PERUMAHAN TUSCANY HILL,23796,0.2428,5777.6688,648.11/1567 - SP/TR 25 April 2025,50.10.29.15/3829-REKTEK/Bid. Taru Tanggal 15 Oktober 2024,2007220014068 Tanggal 20 Juli 2025;500.10.29.7/Kep.429-DLH/2025 Tgl. 10 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
64 / 1682,PT CIPTA BERKAT PROPERTI No Telpon : 081910661980,Ruko Matahari Cigado No 25 Jalan Anggadireja Kel. Baleendah Kec. Baleendah Kab. Bandung,PERUMAHAN GARDEN VIEW CICALENGKA,45666,1,45666,648.11/1682 - SP/TR 06 Mei 2025,50.10.29.15/3156-REKTEK/Bid. Taru Tanggal 05 September 2024,2310210017936 Tanggal 23 Oktober 2021;500.10.29.7/Kep.477-DLH/2025 Tgl. 17 April 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
64 / 1682,PT CIPTA BERKAT PROPERTI No Telpon : 081910661980,Ruko Matahari Cigado No 25 Jalan Anggadireja Kel. Baleendah Kec. Baleendah Kab. Bandung,C. KWT PERUMAHAN,0,1,0,,,,Fungsi Hunian,Fungsi Hunian,1
|
||||||
|
65 / 1644,PT ARGUNA JAYA PROPERTY No Telpon : 081214211164,Jl Pidada IV/4 Denpasar BR/Link Sedana metra Kel. Ubung Kec. Denpasar Utara Kota Denpasar,REVISI 1 PERUMAHAN ARGUNA SINDANGPANON,8553,0.53,4533.09,648.11/1644 - SP/TR 29 April 2025;644/1558 - SP/TR 22 April 2025,503/009/II-DPMPTSP/2020 Tanggal 25 Februari 2020;50.10.29.15/4063-REKTEK/Bid. Taru Tanggal 25 Nopember 2025,9120004890734 Tanggal 03 Agustus 2019;667/2081/TL Tgl. 08 Juni 2020;0609240042720001 Tanggal 06 September 2024,Fungsi Hunian,Fungsi Hunian,1
|
||||||
|
67/ 1370,NENENG FATIMAH No Telpon : 08977980040,Jalan Batu Indah I No 26 RT 002/003 Kel. Batununggal Kec. Bandung Kidul Kota Bandung,PERGUDANGAN DAN PENYIMPANAN,2034,1,2034,644/1370 - SP/TR 26 Maret 2025,50.10.29.15/3340-REKTEK/Bid. Taru Tanggal 18 September 2025,1009240038601 Tanggal 10 September 2024,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
68/ 1374,LILI JOJON No Telpon : 082219855556,Kp. Cibisoro RT 004/008 Desa Nanjung Kec. Mrgaasih Kab. Bandung,PERGUDANGAN DAN PENYIMPANAN,1654,1,1654,644/1374 - SP/TR 26 Maret 2025;644.2/1683 - SP/TR 06 Mei 2025;645/1730 - SP/TR 07 Mei 2025,50.10.29.15/3210-REKTEK/Bid. Taru Tanggal 10 September 2024;400.7.22/1254-KRK/58/Bid. Taru Tanggal 10 Maret 2025;50.10.29.15/3443-REKTEK/Bid. Taru Tanggal 26 September 2024,1220000361065 Tanggal 16 Maret 2021;1712240056863 Tanggal 17 Desember 2024;0103230081544 Tanggal 01 Maret 2023;600.4.5/071/1503-Ktr/Bid. TL/2025 Tanggal 17 April 2025,Usaha Besar (Non-Mikro),Fungsi Usaha,1
|
||||||
|
71/ 1845,PT SANGKURIANG KRAMAT ABADI No Telpon : 082116602145,Kp. Rancakasiat Desa Rancamulya Kec. Pameungpeuk Kab. Bandung,PERUMAHAN CLUSTER GAHARU EMERALD,19889,1,19889,648.11 /1845 - SP/TR 19 Mei 2025,400.7.22/1526-KRK/96/Bid. Taru Tanggal 22 April 2025,0811230037204 Tanggal 08 Nopember 2023;500.10.29.7/Kep. 489-DLH/2025 Tanggal 15 Mei 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
72/ 1731,PT MARGA TIRTA KENCANA No Telpon : 082130000146,Jlan BKR Lingkar selatan No 140 Kota Bandung,PERUMAHAN TAMAN CIBADUYUT INDAH 2 DAN 3,205344,1,205344,648.11 /1731 - SP/TR 07 Mei 2025;648.11 /1946 - SP/TR 22 Mei 2025;643 /1881 - SP/TR 20 Mei 2025;644 /1684 - SP/TR 06 Mei 2025;648.12 /1825 - SP/TR 16 Mei 2025,591.4/002-BPMP/2010 Tanggal 10 Januari 2010;500.10.29.15/3108-REKTEK/Bid.taru Tanggal 29 Agustus 2024;500.10.29.15/3319-REKTEK/TR Tanggal 14 Juli 2023;12092410313204101 Tanggal 12 September 2024;400.7.22/1231-KRK/Bid.Taru Tanggal 06 Maret 2025,667/3803/DLH Tanggal 22 Desember 2016;9120204202309 Tanggal 20 Februari 2019;2002230028317 Tanggal 20 Februari 2023;600.4.5/073/1562-Ktr/Bid.TL/2025 Tanggal 23 April 2025;8120006931402 Tanggal 28 September 2022;12710006324580004 Tanggal 05 Maret 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
77/ 1879,PT PUTRA RAHMAN PRADANA No Telpon : 081312214962,Perum Cemerlang Permai Blok C No 16 Kel. Sukakarya Kec. Warudoyongf Kota Sukabumi,REVISI 1 PERUMAHAN BUKIT PINUS BANIARAN,90711,1,90711,648.11 /1879 - SP/TR 20 Mei 2025,22122310313204009 Tanggal 22 Desember 2023,500.10.29.7/Kep.482-DLH/2025 Tanggal 24 April 2025,Fungsi Hunian,Fungsi Hunian,2
|
||||||
|
56
Dockerfile
Normal file
56
Dockerfile
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
FROM node:18 AS node-base
|
||||||
|
|
||||||
|
# Development stage
|
||||||
|
FROM node-base AS development
|
||||||
|
WORKDIR /var/www
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
EXPOSE 5173
|
||||||
|
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM php:8.2-fpm AS production
|
||||||
|
WORKDIR /var/www
|
||||||
|
|
||||||
|
# Install PHP extensions
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
git curl zip unzip libpng-dev libonig-dev libxml2-dev libzip-dev \
|
||||||
|
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
|
||||||
|
|
||||||
|
# Install Node.js
|
||||||
|
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||||
|
&& apt-get install -y nodejs
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# Install and build frontend assets
|
||||||
|
RUN npm install \
|
||||||
|
&& npm run build \
|
||||||
|
&& ls -la public/build \
|
||||||
|
&& mkdir -p public/assets \
|
||||||
|
&& cp -r public/build/* public/assets/ \
|
||||||
|
&& ls -la public/assets \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& rm -rf public/build
|
||||||
|
|
||||||
|
# Laravel caches
|
||||||
|
RUN php artisan config:clear \
|
||||||
|
&& php artisan route:clear \
|
||||||
|
&& php artisan view:clear \
|
||||||
|
&& php artisan optimize
|
||||||
|
|
||||||
|
RUN php artisan storage:link
|
||||||
|
|
||||||
|
# Permissions
|
||||||
|
RUN chown -R www-data:www-data /var/www && chmod -R 755 /var/www/storage /var/www/public
|
||||||
|
|
||||||
|
EXPOSE 9000
|
||||||
|
CMD ["php-fpm"]
|
||||||
136
README.md
Executable file → Normal file
136
README.md
Executable file → Normal file
@@ -1,66 +1,112 @@
|
|||||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
# Usage icon
|
||||||
|
|
||||||
<p align="center">
|
search or pick icon in <a href="https://icon-sets.iconify.design/mingcute/?keyword=mingcute">here</a>
|
||||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## About Laravel
|
# Set up queue for running automatically
|
||||||
|
|
||||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
- Install Supervisor
|
||||||
|
|
||||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
```
|
||||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
sudo apt update && sudo apt install supervisor -y
|
||||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
```
|
||||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
|
||||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
|
||||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
|
||||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
|
||||||
|
|
||||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
- Create Supervisor Config
|
||||||
|
|
||||||
## Learning Laravel
|
```
|
||||||
|
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
|
||||||
|
|
||||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
[program:laravel-worker]
|
||||||
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
|
command=php /home/arifal/development/sibedas-pbg-web/artisan queue:work --queue=default --timeout=82800 --tries=1
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
numprocs=1
|
||||||
|
redirect_stderr=true
|
||||||
|
stdout_logfile=/home/arifal/development/sibedas-pbg-web/storage/logs/worker.log
|
||||||
|
stopasgroup=true
|
||||||
|
killasgroup=true
|
||||||
|
```
|
||||||
|
|
||||||
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
- Reload Supervisor
|
||||||
|
|
||||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
```
|
||||||
|
sudo supervisorctl reread
|
||||||
|
sudo supervisorctl update
|
||||||
|
sudo supervisorctl start laravel-worker
|
||||||
|
sudo supervisorctl restart laravel-worker
|
||||||
|
sudo supervisorctl status
|
||||||
|
```
|
||||||
|
|
||||||
## Laravel Sponsors
|
# How to running
|
||||||
|
|
||||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
|
- Install composer package
|
||||||
|
|
||||||
### Premium Partners
|
```
|
||||||
|
composer install
|
||||||
|
```
|
||||||
|
|
||||||
- **[Vehikl](https://vehikl.com/)**
|
- Install npm package
|
||||||
- **[Tighten Co.](https://tighten.co)**
|
|
||||||
- **[WebReinvent](https://webreinvent.com/)**
|
|
||||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
|
||||||
- **[64 Robots](https://64robots.com)**
|
|
||||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
|
||||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
|
||||||
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
|
||||||
- **[Jump24](https://jump24.co.uk)**
|
|
||||||
- **[Redberry](https://redberry.international/laravel/)**
|
|
||||||
- **[Active Logic](https://activelogic.com)**
|
|
||||||
- **[byte5](https://byte5.de)**
|
|
||||||
- **[OP.GG](https://op.gg)**
|
|
||||||
|
|
||||||
## Contributing
|
```
|
||||||
|
npm install && npm run build
|
||||||
|
```
|
||||||
|
|
||||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
- Create symlinks storage
|
||||||
|
|
||||||
## Code of Conduct
|
```
|
||||||
|
php artisan storage:link
|
||||||
|
```
|
||||||
|
|
||||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
- Running migration
|
||||||
|
|
||||||
## Security Vulnerabilities
|
```
|
||||||
|
php artisan migrate
|
||||||
|
```
|
||||||
|
|
||||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
- Running seeder
|
||||||
|
|
||||||
## License
|
```
|
||||||
|
php artisan db:seed
|
||||||
|
```
|
||||||
|
|
||||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
- Create view table
|
||||||
|
- excute all sql queries on folder database/view_query
|
||||||
|
|
||||||
|
# Add ENV variable
|
||||||
|
|
||||||
|
- API_KEY_GOOGLE
|
||||||
|
|
||||||
|
```
|
||||||
|
Get api key from google developer console for and turn on spreadsheet api or feaature for google sheet
|
||||||
|
```
|
||||||
|
|
||||||
|
- SPREAD_SHEET_ID
|
||||||
|
|
||||||
|
```
|
||||||
|
Get spreadsheet id from google sheet link
|
||||||
|
```
|
||||||
|
|
||||||
|
- OPENAI_API_KEY
|
||||||
|
|
||||||
|
```
|
||||||
|
Get OpenAI API key from chatgpt subscription
|
||||||
|
```
|
||||||
|
|
||||||
|
- ENV
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
API_KEY_GOOGLE="xxxxx"
|
||||||
|
SPREAD_SHEET_ID="xxxxx"
|
||||||
|
OPENAI_API_KEY="xxxxx"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Technology version
|
||||||
|
|
||||||
|
- php 8.3
|
||||||
|
- Laravel 11
|
||||||
|
- node v22.13.0
|
||||||
|
- npm 10.9.2
|
||||||
|
- mariadb Ver 15.1 Distrib 10.6.18-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
|
||||||
|
- Ubuntu 24.04
|
||||||
|
|||||||
288
app/Console/Commands/CalculateRetributionProposalsCommand.php
Normal file
288
app/Console/Commands/CalculateRetributionProposalsCommand.php
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Models\SpatialPlanning;
|
||||||
|
use App\Models\RetributionProposal;
|
||||||
|
use App\Services\RetributionProposalService;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class CalculateRetributionProposalsCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'retribution:calculate-proposals
|
||||||
|
{--force : Force recalculate existing proposals}
|
||||||
|
{--limit= : Limit number of spatial plannings to process}
|
||||||
|
{--skip-existing : Skip spatial plannings that already have proposals}
|
||||||
|
{--dry-run : Show what would be processed without actually creating proposals}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Calculate retribution proposals for all spatial plannings';
|
||||||
|
|
||||||
|
protected RetributionProposalService $proposalService;
|
||||||
|
|
||||||
|
public function __construct(RetributionProposalService $proposalService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->proposalService = $proposalService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->info('🧮 Starting Retribution Proposal Calculation...');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get processing options
|
||||||
|
$force = $this->option('force');
|
||||||
|
$limit = $this->option('limit') ? (int) $this->option('limit') : null;
|
||||||
|
$skipExisting = $this->option('skip-existing');
|
||||||
|
$dryRun = $this->option('dry-run');
|
||||||
|
|
||||||
|
// Build query for spatial plannings
|
||||||
|
$query = SpatialPlanning::query();
|
||||||
|
|
||||||
|
if ($skipExisting && !$force) {
|
||||||
|
$query->whereDoesntHave('retributionProposals');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($limit) {
|
||||||
|
$query->limit($limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$spatialPlannings = $query->get();
|
||||||
|
$totalCount = $spatialPlannings->count();
|
||||||
|
|
||||||
|
if ($totalCount === 0) {
|
||||||
|
$this->warn('No spatial plannings found to process.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show processing summary
|
||||||
|
$this->info("📊 PROCESSING SUMMARY:");
|
||||||
|
$this->info(" Total Spatial Plannings: {$totalCount}");
|
||||||
|
$this->info(" Force Recalculate: " . ($force ? 'Yes' : 'No'));
|
||||||
|
$this->info(" Skip Existing: " . ($skipExisting ? 'Yes' : 'No'));
|
||||||
|
$this->info(" Dry Run: " . ($dryRun ? 'Yes' : 'No'));
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
if ($dryRun) {
|
||||||
|
$this->showDryRunPreview($spatialPlannings);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm processing
|
||||||
|
if (!$this->confirm("Process {$totalCount} spatial plannings?")) {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process spatial plannings
|
||||||
|
$this->processRetributionCalculations($spatialPlannings, $force);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error('Error during retribution calculation: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show dry run preview
|
||||||
|
*/
|
||||||
|
private function showDryRunPreview($spatialPlannings)
|
||||||
|
{
|
||||||
|
$this->info('🔍 DRY RUN PREVIEW:');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
$processable = 0;
|
||||||
|
$withProposals = 0;
|
||||||
|
$withoutFunction = 0;
|
||||||
|
$withoutArea = 0;
|
||||||
|
|
||||||
|
foreach ($spatialPlannings as $spatial) {
|
||||||
|
$hasProposals = $spatial->retributionProposals()->exists();
|
||||||
|
$buildingFunction = $this->proposalService->detectBuildingFunction($spatial->getBuildingFunctionText());
|
||||||
|
$area = $spatial->getCalculationArea();
|
||||||
|
|
||||||
|
if ($hasProposals) {
|
||||||
|
$withProposals++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$buildingFunction) {
|
||||||
|
$withoutFunction++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($area <= 0) {
|
||||||
|
$withoutArea++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($buildingFunction && $area > 0) {
|
||||||
|
$processable++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->table(
|
||||||
|
['Status', 'Count', 'Description'],
|
||||||
|
[
|
||||||
|
['✅ Processable', $processable, 'Can create retribution proposals'],
|
||||||
|
['🔄 With Existing Proposals', $withProposals, 'Already have proposals (will skip unless --force)'],
|
||||||
|
['❌ Missing Building Function', $withoutFunction, 'Cannot detect building function'],
|
||||||
|
['❌ Missing Area', $withoutArea, 'Area is zero or missing'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->newLine();
|
||||||
|
$this->info("💡 To process: php artisan retribution:calculate-proposals");
|
||||||
|
$this->info("💡 To force recalculate: php artisan retribution:calculate-proposals --force");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process retribution calculations
|
||||||
|
*/
|
||||||
|
private function processRetributionCalculations($spatialPlannings, $force)
|
||||||
|
{
|
||||||
|
$progressBar = $this->output->createProgressBar($spatialPlannings->count());
|
||||||
|
$progressBar->start();
|
||||||
|
|
||||||
|
$stats = [
|
||||||
|
'processed' => 0,
|
||||||
|
'skipped' => 0,
|
||||||
|
'errors' => 0,
|
||||||
|
'created_proposals' => 0
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($spatialPlannings as $spatial) {
|
||||||
|
try {
|
||||||
|
$result = $this->processSingleSpatialPlanning($spatial, $force);
|
||||||
|
|
||||||
|
if ($result['status'] === 'processed') {
|
||||||
|
$stats['processed']++;
|
||||||
|
$stats['created_proposals'] += $result['proposals_created'];
|
||||||
|
} elseif ($result['status'] === 'skipped') {
|
||||||
|
$stats['skipped']++;
|
||||||
|
} else {
|
||||||
|
$stats['errors']++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$stats['errors']++;
|
||||||
|
$this->newLine();
|
||||||
|
$this->error("Error processing spatial planning ID {$spatial->id}: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->finish();
|
||||||
|
$this->newLine(2);
|
||||||
|
|
||||||
|
// Show final statistics
|
||||||
|
$this->showFinalStatistics($stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process single spatial planning
|
||||||
|
*/
|
||||||
|
private function processSingleSpatialPlanning(SpatialPlanning $spatial, $force)
|
||||||
|
{
|
||||||
|
// Check if already has proposals
|
||||||
|
if (!$force && $spatial->retributionProposals()->exists()) {
|
||||||
|
return ['status' => 'skipped', 'reason' => 'already_has_proposals'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect building function
|
||||||
|
$buildingFunction = $this->proposalService->detectBuildingFunction($spatial->getBuildingFunctionText());
|
||||||
|
if (!$buildingFunction) {
|
||||||
|
return ['status' => 'error', 'reason' => 'no_building_function'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get area
|
||||||
|
$totalArea = $spatial->getCalculationArea();
|
||||||
|
if ($totalArea <= 0) {
|
||||||
|
return ['status' => 'error', 'reason' => 'no_area'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get number of floors
|
||||||
|
$numberOfFloors = max(1, $spatial->number_of_floors ?? 1);
|
||||||
|
|
||||||
|
// Delete existing proposals if force mode
|
||||||
|
if ($force) {
|
||||||
|
$spatial->retributionProposals()->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$proposalsCreated = 0;
|
||||||
|
|
||||||
|
// Create proposals for each floor
|
||||||
|
for ($floor = 1; $floor <= $numberOfFloors; $floor++) {
|
||||||
|
// Calculate floor area (distribute total area across floors)
|
||||||
|
$floorArea = $totalArea / $numberOfFloors;
|
||||||
|
|
||||||
|
// Create retribution proposal
|
||||||
|
$proposal = $this->proposalService->createProposalForSpatialPlanning(
|
||||||
|
$spatial,
|
||||||
|
$buildingFunction->id,
|
||||||
|
$floor,
|
||||||
|
$floorArea,
|
||||||
|
$totalArea,
|
||||||
|
"Auto-generated from spatial planning calculation"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($proposal) {
|
||||||
|
$proposalsCreated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'status' => 'processed',
|
||||||
|
'proposals_created' => $proposalsCreated
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show final statistics
|
||||||
|
*/
|
||||||
|
private function showFinalStatistics($stats)
|
||||||
|
{
|
||||||
|
$this->info('✅ CALCULATION COMPLETED!');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
$this->table(
|
||||||
|
['Metric', 'Count'],
|
||||||
|
[
|
||||||
|
['Processed Successfully', $stats['processed']],
|
||||||
|
['Skipped (Already Exists)', $stats['skipped']],
|
||||||
|
['Errors', $stats['errors']],
|
||||||
|
['Total Proposals Created', $stats['created_proposals']],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($stats['errors'] > 0) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->warn("⚠️ {$stats['errors']} spatial plannings had errors:");
|
||||||
|
$this->warn(" • Missing building function detection");
|
||||||
|
$this->warn(" • Missing or zero area");
|
||||||
|
$this->warn(" • Other calculation errors");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stats['processed'] > 0) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->info("🎉 Successfully created {$stats['created_proposals']} retribution proposals!");
|
||||||
|
$this->info("💡 You can view them using: php artisan retribution:list-proposals");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\ServiceSIMBG;
|
use App\Jobs\SyncronizeSIMBG;
|
||||||
|
use App\Services\ServiceSIMBG;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use \Illuminate\Support\Facades\Log;
|
use \Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
@@ -25,10 +26,15 @@ class ExecuteScraping extends Command
|
|||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private $service_simbg;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
SyncronizeSIMBG::dispatch()->onQueue('default');
|
||||||
Log::info("running scheduler daily scraping");
|
Log::info("running scheduler daily scraping");
|
||||||
$service = new ServiceSIMBG();
|
|
||||||
$service->syncTaskList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
317
app/Console/Commands/InitSpatialPlanningDatas.php
Normal file
317
app/Console/Commands/InitSpatialPlanningDatas.php
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\SpatialPlanning;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class InitSpatialPlanningDatas extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'spatial:init {file? : Path to the CSV/Excel file} {--truncate : Clear existing data before import} {--safe-truncate : Clear only spatial plannings without retribution proposals} {--force-truncate : Force truncate by disabling foreign key checks}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Import spatial planning data from CSV/Excel file for retribution';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$filePath = $this->argument('file') ?? 'public/templates/Data_2025___Estimasi_Jumlah_Lantai.csv';
|
||||||
|
$fullPath = storage_path('app/' . $filePath);
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
if (!file_exists($fullPath)) {
|
||||||
|
$this->error("File not found: {$fullPath}");
|
||||||
|
$this->info("Available files in templates:");
|
||||||
|
$this->listAvailableFiles();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle truncate options
|
||||||
|
if (($this->option('truncate') && $this->option('safe-truncate')) ||
|
||||||
|
($this->option('truncate') && $this->option('force-truncate')) ||
|
||||||
|
($this->option('safe-truncate') && $this->option('force-truncate'))) {
|
||||||
|
$this->error('Cannot use multiple truncate options together. Choose only one.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm truncate if requested
|
||||||
|
if ($this->option('truncate')) {
|
||||||
|
if ($this->confirm('This will delete all existing spatial planning data and related retribution proposals. Continue?')) {
|
||||||
|
$this->info('Truncating tables...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// First delete retribution proposals that reference spatial plannings
|
||||||
|
$deletedProposals = DB::table('retribution_proposals')
|
||||||
|
->whereNotNull('spatial_planning_id')
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if ($deletedProposals > 0) {
|
||||||
|
DB::table('retribution_proposals')
|
||||||
|
->whereNotNull('spatial_planning_id')
|
||||||
|
->delete();
|
||||||
|
$this->info("Deleted {$deletedProposals} retribution proposals linked to spatial plannings.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 1: Try truncate with disabled foreign key checks
|
||||||
|
try {
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
|
DB::table('spatial_plannings')->truncate();
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
|
||||||
|
$this->info('Spatial plannings table truncated successfully.');
|
||||||
|
} catch (\Exception $truncateError) {
|
||||||
|
// Method 2: Fallback to delete if truncate fails
|
||||||
|
$this->warn('Truncate failed, using delete method...');
|
||||||
|
$deletedSpatial = DB::table('spatial_plannings')->delete();
|
||||||
|
$this->info("Deleted {$deletedSpatial} spatial planning records.");
|
||||||
|
|
||||||
|
// Reset auto increment
|
||||||
|
DB::statement('ALTER TABLE spatial_plannings AUTO_INCREMENT = 1');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->error('Failed to truncate tables: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force truncate - disable foreign key checks and truncate everything
|
||||||
|
if ($this->option('force-truncate')) {
|
||||||
|
if ($this->confirm('This will FORCE truncate ALL spatial planning data by disabling foreign key checks. This is risky! Continue?')) {
|
||||||
|
$this->info('Force truncating with disabled foreign key checks...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
// Disable foreign key checks
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
|
|
||||||
|
// Truncate both tables
|
||||||
|
DB::table('retribution_proposals')->truncate();
|
||||||
|
DB::table('spatial_plannings')->truncate();
|
||||||
|
|
||||||
|
// Re-enable foreign key checks
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
|
||||||
|
|
||||||
|
$this->info('Force truncate completed successfully.');
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
// Make sure to re-enable foreign key checks even on error
|
||||||
|
try {
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
|
||||||
|
} catch (\Exception $fkError) {
|
||||||
|
$this->error('Failed to re-enable foreign key checks: ' . $fkError->getMessage());
|
||||||
|
}
|
||||||
|
$this->error('Failed to force truncate: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe truncate - only delete spatial plannings without retribution proposals
|
||||||
|
if ($this->option('safe-truncate')) {
|
||||||
|
if ($this->confirm('This will delete only spatial planning data that have no retribution proposals. Continue?')) {
|
||||||
|
$this->info('Safe truncating spatial plannings...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
// Count spatial plannings with retribution proposals
|
||||||
|
$withProposals = DB::table('spatial_plannings')
|
||||||
|
->whereExists(function ($query) {
|
||||||
|
$query->select(DB::raw(1))
|
||||||
|
->from('retribution_proposals')
|
||||||
|
->whereColumn('retribution_proposals.spatial_planning_id', 'spatial_plannings.id');
|
||||||
|
})
|
||||||
|
->count();
|
||||||
|
|
||||||
|
// Delete spatial plannings without retribution proposals
|
||||||
|
$deletedCount = DB::table('spatial_plannings')
|
||||||
|
->whereNotExists(function ($query) {
|
||||||
|
$query->select(DB::raw(1))
|
||||||
|
->from('retribution_proposals')
|
||||||
|
->whereColumn('retribution_proposals.spatial_planning_id', 'spatial_plannings.id');
|
||||||
|
})
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
$this->info("Deleted {$deletedCount} spatial plannings without retribution proposals.");
|
||||||
|
$this->info("Kept {$withProposals} spatial plannings that have retribution proposals.");
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->error('Failed to safe truncate: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("Starting import from: {$filePath}");
|
||||||
|
$this->info("Full path: {$fullPath}");
|
||||||
|
|
||||||
|
try {
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
|
$data = Excel::toArray([], $fullPath);
|
||||||
|
|
||||||
|
if (empty($data) || empty($data[0])) {
|
||||||
|
$this->error('No data found in the file.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $data[0]; // Get first sheet
|
||||||
|
$headers = array_shift($rows); // Remove header row
|
||||||
|
|
||||||
|
$this->info("Found " . count($rows) . " data rows to import.");
|
||||||
|
$this->info("Headers: " . implode(', ', $headers));
|
||||||
|
|
||||||
|
$progressBar = $this->output->createProgressBar(count($rows));
|
||||||
|
$progressBar->start();
|
||||||
|
|
||||||
|
$imported = 0;
|
||||||
|
$skipped = 0;
|
||||||
|
|
||||||
|
foreach ($rows as $index => $row) {
|
||||||
|
try {
|
||||||
|
// Skip empty rows
|
||||||
|
if (empty(array_filter($row))) {
|
||||||
|
$skipped++;
|
||||||
|
$progressBar->advance();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map CSV columns to model attributes
|
||||||
|
$spatialData = [
|
||||||
|
'name' => $this->cleanString($row[1] ?? ''), // pemohon
|
||||||
|
'location' => $this->cleanString($row[2] ?? ''), // alamat
|
||||||
|
'activities' => $this->cleanString($row[3] ?? ''), // activities
|
||||||
|
'land_area' => $this->cleanNumber($row[4] ?? 0), // luas_lahan
|
||||||
|
'site_bcr' => $this->cleanNumber($row[5] ?? 0), // bcr_kawasan
|
||||||
|
'area' => $this->cleanNumber($row[6] ?? 0), // area
|
||||||
|
'no_tapak' => $this->cleanString($row[7] ?? ''), // no_tapak
|
||||||
|
'no_skkl' => $this->cleanString($row[8] ?? ''), // no_skkl
|
||||||
|
'no_ukl' => $this->cleanString($row[9] ?? ''), // no_ukl
|
||||||
|
'building_function' => $this->cleanString($row[10] ?? ''), // fungsi_bangunan
|
||||||
|
'sub_building_function' => $this->cleanString($row[11] ?? ''), // sub_fungsi_bangunan
|
||||||
|
'number_of_floors' => $this->cleanNumber($row[12] ?? 1), // jumlah_lantai
|
||||||
|
'number' => $this->cleanString($row[0] ?? ''), // no
|
||||||
|
'date' => now(), // Set current date
|
||||||
|
'kbli' => null, // Not in CSV, set as null
|
||||||
|
];
|
||||||
|
|
||||||
|
// Validate required fields
|
||||||
|
if (empty($spatialData['name']) && empty($spatialData['activities'])) {
|
||||||
|
$skipped++;
|
||||||
|
$progressBar->advance();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpatialPlanning::create($spatialData);
|
||||||
|
$imported++;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->error("Error importing row " . ($index + 2) . ": " . $e->getMessage());
|
||||||
|
$skipped++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->finish();
|
||||||
|
$this->newLine(2);
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
|
$this->info("Import completed successfully!");
|
||||||
|
$this->info("Imported: {$imported} records");
|
||||||
|
$this->info("Skipped: {$skipped} records");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
DB::rollBack();
|
||||||
|
$this->error("Import failed: " . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean string data
|
||||||
|
*/
|
||||||
|
private function cleanString($value)
|
||||||
|
{
|
||||||
|
if (is_null($value)) return null;
|
||||||
|
return trim(str_replace(["\n", "\r", "\t"], ' ', $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean numeric data
|
||||||
|
*/
|
||||||
|
private function cleanNumber($value)
|
||||||
|
{
|
||||||
|
if (is_null($value) || $value === '') return 0;
|
||||||
|
|
||||||
|
// Remove non-numeric characters except decimal point
|
||||||
|
$cleaned = preg_replace('/[^0-9.]/', '', $value);
|
||||||
|
|
||||||
|
return is_numeric($cleaned) ? (float) $cleaned : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List available template files
|
||||||
|
*/
|
||||||
|
private function listAvailableFiles()
|
||||||
|
{
|
||||||
|
$templatesPath = storage_path('app/public/templates');
|
||||||
|
if (is_dir($templatesPath)) {
|
||||||
|
$this->info("Files in storage/app/public/templates:");
|
||||||
|
$extensions = ['csv', 'xlsx', 'xls'];
|
||||||
|
foreach ($extensions as $ext) {
|
||||||
|
$files = glob($templatesPath . '/*.' . $ext);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$this->line(' - ' . basename($file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$publicTemplatesPath = public_path('templates');
|
||||||
|
if (is_dir($publicTemplatesPath)) {
|
||||||
|
$this->info("Files in public/templates:");
|
||||||
|
$extensions = ['csv', 'xlsx', 'xls'];
|
||||||
|
foreach ($extensions as $ext) {
|
||||||
|
$files = glob($publicTemplatesPath . '/*.' . $ext);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$this->line(' - ' . basename($file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Models\SpatialPlanning;
|
||||||
|
use App\Models\RetributionProposal;
|
||||||
|
use App\Services\RetributionProposalService;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ProcessSpatialPlanningRetributionCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'spatial:process-retribution
|
||||||
|
{--all : Process all spatial plannings}
|
||||||
|
{--new-only : Process only spatial plannings without retribution proposals}
|
||||||
|
{--force : Force recalculate existing retribution proposals}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Process and save retribution calculations for spatial plannings';
|
||||||
|
|
||||||
|
protected RetributionProposalService $proposalService;
|
||||||
|
|
||||||
|
public function __construct(RetributionProposalService $proposalService)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->proposalService = $proposalService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$this->info('🏗️ Processing Spatial Planning Retribution Calculations...');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get options
|
||||||
|
$processAll = $this->option('all');
|
||||||
|
$newOnly = $this->option('new-only');
|
||||||
|
$force = $this->option('force');
|
||||||
|
|
||||||
|
// Build query
|
||||||
|
$query = SpatialPlanning::query();
|
||||||
|
|
||||||
|
if ($newOnly || (!$processAll && !$force)) {
|
||||||
|
$query->whereDoesntHave('retributionProposals');
|
||||||
|
$this->info('📋 Mode: Processing only spatial plannings WITHOUT retribution proposals');
|
||||||
|
} elseif ($processAll) {
|
||||||
|
$this->info('📋 Mode: Processing ALL spatial plannings');
|
||||||
|
}
|
||||||
|
|
||||||
|
$spatialPlannings = $query->get();
|
||||||
|
$totalCount = $spatialPlannings->count();
|
||||||
|
|
||||||
|
if ($totalCount === 0) {
|
||||||
|
$this->warn('❌ No spatial plannings found to process.');
|
||||||
|
$this->info('💡 Try running: php artisan spatial:init first');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info("📊 Found {$totalCount} spatial plannings to process");
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Show preview of what will be processed
|
||||||
|
$this->showProcessingPreview($spatialPlannings);
|
||||||
|
|
||||||
|
// Confirm processing
|
||||||
|
if (!$this->confirm("Process {$totalCount} spatial plannings and create retribution proposals?")) {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all spatial plannings
|
||||||
|
$this->processAllSpatialPlannings($spatialPlannings, $force);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->error('❌ Error during processing: ' . $e->getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show processing preview
|
||||||
|
*/
|
||||||
|
private function showProcessingPreview($spatialPlannings)
|
||||||
|
{
|
||||||
|
$this->info('🔍 PREVIEW:');
|
||||||
|
|
||||||
|
$canProcess = 0;
|
||||||
|
$cannotProcess = 0;
|
||||||
|
$hasExisting = 0;
|
||||||
|
|
||||||
|
$sampleData = [];
|
||||||
|
$errorReasons = [];
|
||||||
|
|
||||||
|
foreach ($spatialPlannings->take(5) as $spatial) {
|
||||||
|
$buildingFunction = $this->proposalService->detectBuildingFunction($spatial->getBuildingFunctionText());
|
||||||
|
$area = $spatial->getCalculationArea();
|
||||||
|
$floors = max(1, $spatial->number_of_floors ?? 1);
|
||||||
|
$hasProposals = $spatial->retributionProposals()->exists();
|
||||||
|
|
||||||
|
if ($hasProposals) {
|
||||||
|
$hasExisting++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($buildingFunction && $area > 0) {
|
||||||
|
$canProcess++;
|
||||||
|
$sampleData[] = [
|
||||||
|
'ID' => $spatial->id,
|
||||||
|
'Name' => substr($spatial->name ?? 'N/A', 0, 30),
|
||||||
|
'Function' => $buildingFunction->name ?? 'N/A',
|
||||||
|
'Area' => number_format($area, 2),
|
||||||
|
'Floors' => $floors,
|
||||||
|
'Status' => $hasProposals ? '🔄 Has Proposals' : '✅ Ready'
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$cannotProcess++;
|
||||||
|
if (!$buildingFunction) {
|
||||||
|
$errorReasons[] = 'Missing building function';
|
||||||
|
}
|
||||||
|
if ($area <= 0) {
|
||||||
|
$errorReasons[] = 'Missing/zero area';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show sample data table
|
||||||
|
if (!empty($sampleData)) {
|
||||||
|
$this->table(
|
||||||
|
['ID', 'Name', 'Function', 'Area (m²)', 'Floors', 'Status'],
|
||||||
|
$sampleData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show summary
|
||||||
|
$this->newLine();
|
||||||
|
$this->info("📈 SUMMARY:");
|
||||||
|
$this->info(" ✅ Can Process: {$canProcess}");
|
||||||
|
$this->info(" ❌ Cannot Process: {$cannotProcess}");
|
||||||
|
$this->info(" 🔄 Has Existing Proposals: {$hasExisting}");
|
||||||
|
|
||||||
|
if ($cannotProcess > 0) {
|
||||||
|
$this->warn(" ⚠️ Common Issues: " . implode(', ', array_unique($errorReasons)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->newLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process all spatial plannings
|
||||||
|
*/
|
||||||
|
private function processAllSpatialPlannings($spatialPlannings, $force)
|
||||||
|
{
|
||||||
|
$this->info('🚀 Starting processing...');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
$progressBar = $this->output->createProgressBar($spatialPlannings->count());
|
||||||
|
$progressBar->start();
|
||||||
|
|
||||||
|
$stats = [
|
||||||
|
'processed' => 0,
|
||||||
|
'skipped' => 0,
|
||||||
|
'errors' => 0,
|
||||||
|
'total_proposals' => 0,
|
||||||
|
'total_amount' => 0
|
||||||
|
];
|
||||||
|
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
foreach ($spatialPlannings as $spatial) {
|
||||||
|
try {
|
||||||
|
$result = $this->processSingleSpatialPlanning($spatial, $force);
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
$stats['processed']++;
|
||||||
|
$stats['total_proposals'] += $result['proposals_count'];
|
||||||
|
$stats['total_amount'] += $result['total_amount'];
|
||||||
|
} elseif ($result['skipped']) {
|
||||||
|
$stats['skipped']++;
|
||||||
|
} else {
|
||||||
|
$stats['errors']++;
|
||||||
|
$errors[] = "ID {$spatial->id}: " . $result['error'];
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$stats['errors']++;
|
||||||
|
$errors[] = "ID {$spatial->id}: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
$progressBar->finish();
|
||||||
|
$this->newLine(2);
|
||||||
|
|
||||||
|
// Show final results
|
||||||
|
$this->showFinalResults($stats, $errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process single spatial planning
|
||||||
|
*/
|
||||||
|
private function processSingleSpatialPlanning(SpatialPlanning $spatial, $force)
|
||||||
|
{
|
||||||
|
// Check if already has proposals
|
||||||
|
if (!$force && $spatial->retributionProposals()->exists()) {
|
||||||
|
return ['success' => false, 'skipped' => true];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect building function
|
||||||
|
$buildingFunction = $this->proposalService->detectBuildingFunction($spatial->getBuildingFunctionText());
|
||||||
|
if (!$buildingFunction) {
|
||||||
|
return ['success' => false, 'skipped' => false, 'error' => 'Cannot detect building function from: ' . $spatial->getBuildingFunctionText()];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get area
|
||||||
|
$totalArea = $spatial->getCalculationArea();
|
||||||
|
if ($totalArea <= 0) {
|
||||||
|
return ['success' => false, 'skipped' => false, 'error' => 'Area is zero or missing'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get number of floors
|
||||||
|
$numberOfFloors = max(1, $spatial->number_of_floors ?? 1);
|
||||||
|
|
||||||
|
// Delete existing proposals if force mode
|
||||||
|
if ($force) {
|
||||||
|
$spatial->retributionProposals()->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$proposalsCount = 0;
|
||||||
|
$totalAmount = 0;
|
||||||
|
|
||||||
|
// Create single proposal for the spatial planning (not per floor to prevent duplicates)
|
||||||
|
// Use the highest floor for IP ketinggian calculation (worst case scenario)
|
||||||
|
$highestFloor = $numberOfFloors;
|
||||||
|
|
||||||
|
$proposal = $this->proposalService->createProposalForSpatialPlanning(
|
||||||
|
$spatial,
|
||||||
|
$buildingFunction->id,
|
||||||
|
$highestFloor, // Use highest floor for calculation
|
||||||
|
$totalArea, // Use total area, not divided by floors
|
||||||
|
$totalArea,
|
||||||
|
"Auto-calculated from spatial planning data (floors: {$numberOfFloors})"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($proposal) {
|
||||||
|
$proposalsCount = 1;
|
||||||
|
$totalAmount = $proposal->total_retribution_amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'skipped' => false,
|
||||||
|
'proposals_count' => $proposalsCount,
|
||||||
|
'total_amount' => $totalAmount
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show final results
|
||||||
|
*/
|
||||||
|
private function showFinalResults($stats, $errors)
|
||||||
|
{
|
||||||
|
$this->info('🎉 PROCESSING COMPLETED!');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Main statistics table
|
||||||
|
$this->table(
|
||||||
|
['Metric', 'Count'],
|
||||||
|
[
|
||||||
|
['✅ Successfully Processed', $stats['processed']],
|
||||||
|
['⏭️ Skipped (Already Has Proposals)', $stats['skipped']],
|
||||||
|
['❌ Errors', $stats['errors']],
|
||||||
|
['📄 Total Proposals Created', $stats['total_proposals']],
|
||||||
|
['💰 Total Retribution Amount', 'Rp ' . number_format($stats['total_amount'], 2)],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
if ($stats['processed'] > 0) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->info("🎊 SUCCESS!");
|
||||||
|
$this->info(" 📊 Created {$stats['total_proposals']} retribution proposals");
|
||||||
|
$this->info(" 💵 Total calculated amount: Rp " . number_format($stats['total_amount'], 2));
|
||||||
|
$this->info(" 📋 Processed {$stats['processed']} spatial plannings");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show errors if any
|
||||||
|
if ($stats['errors'] > 0) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->warn("⚠️ ERRORS ENCOUNTERED:");
|
||||||
|
foreach (array_slice($errors, 0, 10) as $error) {
|
||||||
|
$this->warn(" • {$error}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($errors) > 10) {
|
||||||
|
$this->warn(" ... and " . (count($errors) - 10) . " more errors");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show next steps
|
||||||
|
$this->newLine();
|
||||||
|
$this->info("📋 NEXT STEPS:");
|
||||||
|
$this->info(" • View proposals: php artisan spatial:check-constraints");
|
||||||
|
$this->info(" • Check database: SELECT COUNT(*) FROM retribution_proposals;");
|
||||||
|
$this->info(" • Access via API: GET /api/retribution-proposals");
|
||||||
|
}
|
||||||
|
}
|
||||||
45
app/Console/Commands/ScrapingData.php
Normal file
45
app/Console/Commands/ScrapingData.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Jobs\ScrapingDataJob;
|
||||||
|
use App\Models\ImportDatasource;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
|
use GuzzleHttp\Client; // Import Guzzle Client
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ScrapingData extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'app:scraping-data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Command description';
|
||||||
|
/**
|
||||||
|
* Inject dependencies.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
dispatch(new ScrapingDataJob());
|
||||||
|
|
||||||
|
$this->info("Scraping job dispatched successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
33
app/Console/Commands/ScrapingLeaderData.php
Normal file
33
app/Console/Commands/ScrapingLeaderData.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class ScrapingLeaderData extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'app:scraping-leader-data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Scraping leader data from google spreadsheet and save to database';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$service_google_sheet = app(ServiceGoogleSheet::class);
|
||||||
|
$service_google_sheet->sync_leader_data();
|
||||||
|
$this->info('Leader data synced successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
125
app/Console/Commands/TestExcelFormulaCommand.php
Normal file
125
app/Console/Commands/TestExcelFormulaCommand.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Services\DynamicRetributionCalculationService;
|
||||||
|
|
||||||
|
class TestExcelFormulaCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*/
|
||||||
|
protected $signature = 'test:excel-formula';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*/
|
||||||
|
protected $description = 'Test Excel formula implementation for PBG retribution calculation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$service = new DynamicRetributionCalculationService();
|
||||||
|
|
||||||
|
$this->info('=== TESTING RUNDOWN 4 IMPLEMENTATION ===');
|
||||||
|
$this->info('Formula: =ROUNDDOWN(($E13*($F13+$G13+(0.5*I$3))),4)');
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Test 1: Hunian Sederhana
|
||||||
|
$this->info('1. HUNIAN SEDERHANA (1 Lantai, 100 m²)');
|
||||||
|
|
||||||
|
$result1 = $service->calculateRetribution(
|
||||||
|
buildingFunctionId: 10, // HUNIAN_SEDERHANA
|
||||||
|
floorLevel: 1,
|
||||||
|
luasBangunan: 100,
|
||||||
|
indeksLokasi: 'sedang',
|
||||||
|
includeInfrastructure: true
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result1['success']) {
|
||||||
|
$rundown4 = $result1['calculation_breakdown']['rundown_4_calculation'];
|
||||||
|
$retribution = $result1['calculation_breakdown']['retribution_calculation'];
|
||||||
|
|
||||||
|
$this->info(' ✓ Before ROUNDDOWN: ' . $rundown4['before_rounddown']);
|
||||||
|
$this->info(' ✓ After ROUNDDOWN(4): ' . $rundown4['after_rounddown']);
|
||||||
|
$this->info(' ✓ Basic Retribution: Rp ' . number_format($retribution['basic_amount']));
|
||||||
|
$this->info(' ✓ Infrastructure: Rp ' . number_format($retribution['infrastructure_amount']));
|
||||||
|
$this->info(' 💰 TOTAL: Rp ' . number_format($retribution['total_amount']));
|
||||||
|
} else {
|
||||||
|
$this->error(' ❌ Error: ' . $result1['error']);
|
||||||
|
}
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Test 2: Usaha Besar
|
||||||
|
$this->info('2. USAHA BESAR (3 Lantai, 200 m²)');
|
||||||
|
|
||||||
|
$result2 = $service->calculateRetribution(
|
||||||
|
buildingFunctionId: 9, // USAHA_BESAR
|
||||||
|
floorLevel: 3,
|
||||||
|
luasBangunan: 200,
|
||||||
|
indeksLokasi: 'tinggi',
|
||||||
|
includeInfrastructure: true
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result2['success']) {
|
||||||
|
$rundown4 = $result2['calculation_breakdown']['rundown_4_calculation'];
|
||||||
|
$retribution = $result2['calculation_breakdown']['retribution_calculation'];
|
||||||
|
|
||||||
|
$this->info(' ✓ Rundown 4 Result: ' . $rundown4['after_rounddown']);
|
||||||
|
$this->info(' ✓ Basic: Rp ' . number_format($retribution['basic_amount']));
|
||||||
|
$this->info(' ✓ Infrastructure: Rp ' . number_format($retribution['infrastructure_amount']));
|
||||||
|
$this->info(' 💰 TOTAL: Rp ' . number_format($retribution['total_amount']));
|
||||||
|
}
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Test 3: Keagamaan (Free)
|
||||||
|
$this->info('3. KEAGAMAAN (2 Lantai, 150 m²) - BEBAS RETRIBUSI');
|
||||||
|
|
||||||
|
$result3 = $service->calculateRetribution(
|
||||||
|
buildingFunctionId: 1, // KEAGAMAAN
|
||||||
|
floorLevel: 2,
|
||||||
|
luasBangunan: 150,
|
||||||
|
indeksLokasi: 'sedang',
|
||||||
|
includeInfrastructure: true
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result3['success']) {
|
||||||
|
$this->info(' ✓ Rundown 4 Result: ' . $result3['results']['h5_rundown4']);
|
||||||
|
$this->info(' 💸 RETRIBUSI BEBAS: Rp ' . number_format($result3['results']['total_retribution']));
|
||||||
|
}
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
// Test 4: Multi-Floor Calculation
|
||||||
|
$this->info('4. CAMPURAN BESAR - Multi Lantai (1-4 Lantai, 300 m²)');
|
||||||
|
|
||||||
|
$result4 = $service->calculateMultiFloorRetribution(
|
||||||
|
buildingFunctionId: 7, // CAMPURAN_BESAR
|
||||||
|
floors: [1, 2, 3, 4],
|
||||||
|
luasBangunan: 300,
|
||||||
|
indeksLokasi: 'tinggi'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($result4['success']) {
|
||||||
|
$this->info(' ✓ Per Floor Calculations:');
|
||||||
|
foreach ($result4['floor_details'] as $floor => $detail) {
|
||||||
|
$this->info(" Lantai {$floor}: H5={$detail['h5_rundown4']}, Total=Rp " . number_format($detail['total_retribution']));
|
||||||
|
}
|
||||||
|
$this->info(' 💰 TOTAL SEMUA LANTAI: Rp ' . number_format($result4['total_retribution']));
|
||||||
|
}
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
$this->info('=== RUNDOWN 4 VERIFICATION ===');
|
||||||
|
$this->info('✅ Formula: =ROUNDDOWN(($E13*($F13+$G13+(0.5*I$3))),4)');
|
||||||
|
$this->info('✅ ROUNDDOWN function with 4 decimal precision');
|
||||||
|
$this->info('✅ Tarif Dasar: Rp 7.035.000');
|
||||||
|
$this->info('✅ Infrastructure calculation: O3 * basic');
|
||||||
|
$this->info('✅ Code simplified - unused formulas removed');
|
||||||
|
$this->newLine();
|
||||||
|
$this->info('🎉 RUNDOWN 4 Implementation is CLEAN and VERIFIED!');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Enums/PbgTaskApplicationTypes.php
Normal file
25
app/Enums/PbgTaskApplicationTypes.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum PbgTaskApplicationTypes: string
|
||||||
|
{
|
||||||
|
case PERSETUJUAN_BG = '1';
|
||||||
|
case PERUBAHAN_BG = '2';
|
||||||
|
case SLF_BB = '4';
|
||||||
|
case SLF = '5';
|
||||||
|
public static function labels(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
null => "Pilih Application Type",
|
||||||
|
self::PERSETUJUAN_BG->value => 'Persetujuan Bangunan Gedung',
|
||||||
|
self::PERUBAHAN_BG->value => 'Perubahan Bangunan Gedung',
|
||||||
|
self::SLF_BB->value => 'Sertifikat Laik Fungsi - Bangunan Baru',
|
||||||
|
self::SLF->value => 'Sertifikat Laik Fungsi',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public static function getLabel(?string $status): ?string
|
||||||
|
{
|
||||||
|
return self::labels()[$status] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/Enums/PbgTaskFilterData.php
Normal file
22
app/Enums/PbgTaskFilterData.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum PbgTaskFilterData : string
|
||||||
|
{
|
||||||
|
case non_business = 'non-business';
|
||||||
|
case business = 'business';
|
||||||
|
case verified = 'verified';
|
||||||
|
case non_verified = 'non-verified';
|
||||||
|
case all = 'all';
|
||||||
|
|
||||||
|
public static function getAllOptions() : array {
|
||||||
|
return [
|
||||||
|
self::all->value => 'Potensi Berkas',
|
||||||
|
self::business->value => 'Usaha',
|
||||||
|
self::non_business->value => 'Bukan Usaha',
|
||||||
|
self::verified->value => 'Terverifikasi',
|
||||||
|
self::non_verified->value => 'Belum Terverifikasi',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
59
app/Enums/PbgTaskStatus.php
Normal file
59
app/Enums/PbgTaskStatus.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum PbgTaskStatus: int
|
||||||
|
{
|
||||||
|
case VERIFIKASI_KELENGKAPAN = 1;
|
||||||
|
case PERBAIKAN_DOKUMEN = 2;
|
||||||
|
case PERMOHONAN_DIBATALKAN = 3;
|
||||||
|
case MENUNGGU_PENUGASAN_TPT_TPA = 4;
|
||||||
|
case MENUNGGU_JADWAL_KONSULTASI = 5;
|
||||||
|
case PELAKSANAAN_KONSULTASI = 6;
|
||||||
|
case PERBAIKAN_DOKUMEN_KONSULTASI = 8;
|
||||||
|
case PERMOHONAN_DITOLAK = 9;
|
||||||
|
case PERHITUNGAN_RETRIBUSI = 10;
|
||||||
|
case MENUNGGU_PEMBAYARAN_RETRIBUSI = 14;
|
||||||
|
case VERIFIKASI_PEMBAYARAN_RETRIBUSI = 15;
|
||||||
|
case RETRIBUSI_TIDAK_SESUAI = 16;
|
||||||
|
case VERIFIKASI_SK_PBG = 18;
|
||||||
|
case PENERBITAN_SK_PBG = 19;
|
||||||
|
case SK_PBG_TERBIT = 20;
|
||||||
|
case PENERBITAN_SPPST = 24;
|
||||||
|
case PROSES_PENERBITAN_SKRD = 25;
|
||||||
|
case MENUNGGU_PENUGASAN_TPT = 26;
|
||||||
|
case VERIFIKASI_DATA_TPT = 27;
|
||||||
|
case SERTIFIKAT_SLF_TERBIT = 28;
|
||||||
|
|
||||||
|
public static function getStatuses(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
null => "Pilih Status",
|
||||||
|
self::VERIFIKASI_KELENGKAPAN->value => "Verifikasi Kelengkapan Dokumen",
|
||||||
|
self::PERBAIKAN_DOKUMEN->value => "Perbaikan Dokumen",
|
||||||
|
self::PERMOHONAN_DIBATALKAN->value => "Permohonan Dibatalkan",
|
||||||
|
self::MENUNGGU_PENUGASAN_TPT_TPA->value => "Menunggu Penugasan TPT/TPA",
|
||||||
|
self::MENUNGGU_JADWAL_KONSULTASI->value => "Menunggu Jadwal Konsultasi",
|
||||||
|
self::PELAKSANAAN_KONSULTASI->value => "Pelaksanaan Konsultasi",
|
||||||
|
self::PERBAIKAN_DOKUMEN_KONSULTASI->value => "Perbaikan Dokumen Konsultasi",
|
||||||
|
self::PERMOHONAN_DITOLAK->value => "Permohonan Ditolak",
|
||||||
|
self::PERHITUNGAN_RETRIBUSI->value => "Perhitungan Retribusi",
|
||||||
|
self::MENUNGGU_PEMBAYARAN_RETRIBUSI->value => "Menunggu Pembayaran Retribusi",
|
||||||
|
self::VERIFIKASI_PEMBAYARAN_RETRIBUSI->value => "Verifikasi Pembayaran Retribusi",
|
||||||
|
self::RETRIBUSI_TIDAK_SESUAI->value => "Retribusi Tidak Sesuai",
|
||||||
|
self::VERIFIKASI_SK_PBG->value => "Verifikasi SK PBG",
|
||||||
|
self::PENERBITAN_SK_PBG->value => "Penerbitan SK PBG",
|
||||||
|
self::SK_PBG_TERBIT->value => "SK PBG Terbit",
|
||||||
|
self::PENERBITAN_SPPST->value => "Penerbitan SPPST",
|
||||||
|
self::PROSES_PENERBITAN_SKRD->value => "Proses Penerbitan SKRD",
|
||||||
|
self::MENUNGGU_PENUGASAN_TPT->value => "Menunggu Penugasan TPT",
|
||||||
|
self::VERIFIKASI_DATA_TPT->value => "Verifikasi Data TPT",
|
||||||
|
self::SERTIFIKAT_SLF_TERBIT->value => "Sertifikat SLF Terbit",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getLabel(?int $status): ?string
|
||||||
|
{
|
||||||
|
return self::getStatuses()[$status] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/Exports/DistrictPaymentRecapExport.php
Normal file
31
app/Exports/DistrictPaymentRecapExport.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class DistrictPaymentRecapExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Kecamatan',
|
||||||
|
'Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
90
app/Exports/ReportDirectorExport.php
Normal file
90
app/Exports/ReportDirectorExport.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||||
|
|
||||||
|
class ReportDirectorExport implements FromCollection, WithHeadings, WithMapping
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return BigdataResume::select(
|
||||||
|
'potention_count',
|
||||||
|
'potention_sum',
|
||||||
|
'non_verified_count',
|
||||||
|
'non_verified_sum',
|
||||||
|
'verified_count',
|
||||||
|
'verified_sum',
|
||||||
|
'business_count',
|
||||||
|
'business_sum',
|
||||||
|
'non_business_count',
|
||||||
|
'non_business_sum',
|
||||||
|
'spatial_count',
|
||||||
|
'spatial_sum',
|
||||||
|
'waiting_click_dpmptsp_count',
|
||||||
|
'waiting_click_dpmptsp_sum',
|
||||||
|
'issuance_realization_pbg_count',
|
||||||
|
'issuance_realization_pbg_sum',
|
||||||
|
'process_in_technical_office_count',
|
||||||
|
'process_in_technical_office_sum',
|
||||||
|
'year',
|
||||||
|
'created_at'
|
||||||
|
)->orderBy('id', 'desc')->get();
|
||||||
|
}
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
"Jumlah Potensi" ,
|
||||||
|
"Total Potensi" ,
|
||||||
|
"Jumlah Berkas Belum Terverifikasi" ,
|
||||||
|
"Total Berkas Belum Terverifikasi" ,
|
||||||
|
"Jumlah Berkas Terverifikasi" ,
|
||||||
|
"Total Berkas Terverifikasi" ,
|
||||||
|
"Jumlah Usaha" ,
|
||||||
|
"Total Usaha" ,
|
||||||
|
"Jumlah Non Usaha" ,
|
||||||
|
"Total Non Usaha" ,
|
||||||
|
"Jumlah Tata Ruang" ,
|
||||||
|
"Total Tata Ruang" ,
|
||||||
|
"Jumlah Menunggu Klik DPMPTSP" ,
|
||||||
|
"Total Menunggu Klik DPMPTSP" ,
|
||||||
|
"Jumlah Realisasi Terbit PBG" ,
|
||||||
|
"Total Realisasi Terbit PBG" ,
|
||||||
|
"Jumlah Proses Dinas Teknis" ,
|
||||||
|
"Total Proses Dinas Teknis",
|
||||||
|
"Tahun",
|
||||||
|
"Created"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function map($row): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
$row->potention_count,
|
||||||
|
$row->potention_sum,
|
||||||
|
$row->non_verified_count,
|
||||||
|
$row->non_verified_sum,
|
||||||
|
$row->verified_count,
|
||||||
|
$row->verified_sum,
|
||||||
|
$row->business_count,
|
||||||
|
$row->business_sum,
|
||||||
|
$row->non_business_count,
|
||||||
|
$row->non_business_sum,
|
||||||
|
$row->spatial_count,
|
||||||
|
$row->spatial_sum,
|
||||||
|
$row->waiting_click_dpmptsp_count,
|
||||||
|
$row->waiting_click_dpmptsp_sum,
|
||||||
|
$row->issuance_realization_pbg_count,
|
||||||
|
$row->issuance_realization_pbg_sum,
|
||||||
|
$row->process_in_technical_office_count,
|
||||||
|
$row->process_in_technical_office_sum,
|
||||||
|
$row->year,
|
||||||
|
$row->created_at ? $row->created_at->format('Y-m-d H:i:s') : null, // Format created_at as Y-m-d
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
71
app/Exports/ReportPaymentRecapExport.php
Normal file
71
app/Exports/ReportPaymentRecapExport.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportPaymentRecapExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
protected $startDate;
|
||||||
|
protected $endDate;
|
||||||
|
public function __construct($startDate, $endDate){
|
||||||
|
$this->startDate = $startDate;
|
||||||
|
$this->endDate = $endDate;
|
||||||
|
}
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($this->startDate && $this->endDate) {
|
||||||
|
$query->whereBetween('created_at', [$this->startDate, $this->endDate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $query->get();
|
||||||
|
|
||||||
|
$categoryMap = [
|
||||||
|
'potention_sum' => 'Potensi',
|
||||||
|
'non_verified_sum' => 'Belum Terverifikasi',
|
||||||
|
'verified_sum' => 'Terverifikasi',
|
||||||
|
'business_sum' => 'Usaha',
|
||||||
|
'non_business_sum' => 'Non Usaha',
|
||||||
|
'spatial_sum' => 'Tata Ruang',
|
||||||
|
'waiting_click_dpmptsp_sum' => 'Menunggu Klik DPMPTSP',
|
||||||
|
'issuance_realization_pbg_sum' => 'Realisasi Terbit PBG',
|
||||||
|
'process_in_technical_office_sum' => 'Proses Di Dinas Teknis',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Restructure response
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$data[] = [
|
||||||
|
'category' => $categoryMap[$key] ?? $key, // Map category
|
||||||
|
'nominal' => number_format($value, 0, ',', '.'), // Format number
|
||||||
|
'created_at' => $createdAt->format('Y-m-d H:i:s'), // Format date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collect($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Kategori',
|
||||||
|
'Nominal',
|
||||||
|
'Created'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Exports/ReportPbgPtspExport.php
Normal file
32
app/Exports/ReportPbgPtspExport.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportPbgPtspExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return PbgTask::select(
|
||||||
|
'status_name',
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Status Name',
|
||||||
|
'Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
25
app/Exports/ReportTourismExport.php
Normal file
25
app/Exports/ReportTourismExport.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
|
class ReportTourismExport implements FromCollection, WithHeadings
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return TourismBasedKBLI::select('kbli_title', 'total_records')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array{
|
||||||
|
return [
|
||||||
|
'Jenis Bisnis Pariwisata',
|
||||||
|
'Jumlah Total'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,10 +75,10 @@ class AdvertisementController extends Controller
|
|||||||
{
|
{
|
||||||
$data = $request->validated();
|
$data = $request->validated();
|
||||||
|
|
||||||
// Cari village_code berdasarkan village_name
|
|
||||||
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->value('village_code');
|
|
||||||
// Cari district_code berdasarkan district_name
|
// Cari district_code berdasarkan district_name
|
||||||
$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');
|
||||||
|
// 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
|
// Tambahkan village_code dan district_code ke data
|
||||||
$data['village_code'] = $village_code;
|
$data['village_code'] = $village_code;
|
||||||
@@ -142,10 +142,10 @@ class AdvertisementController extends Controller
|
|||||||
{
|
{
|
||||||
$data = $request->validated();
|
$data = $request->validated();
|
||||||
|
|
||||||
// Cari village_code berdasarkan village_name
|
|
||||||
$village_code = DB::table('villages')->where('village_name', $data['village_name'])->value('village_code');
|
|
||||||
// Cari district_code berdasarkan district_name
|
// Cari district_code berdasarkan district_name
|
||||||
$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');
|
||||||
|
// 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
|
// Tambahkan village_code dan district_code ke data
|
||||||
$data['village_code'] = $village_code;
|
$data['village_code'] = $village_code;
|
||||||
@@ -196,4 +196,17 @@ class AdvertisementController extends Controller
|
|||||||
|
|
||||||
return response()->json($results);
|
return response()->json($results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function downloadExcelAdvertisement()
|
||||||
|
{
|
||||||
|
$filePath = public_path('templates/template_reklame.xlsx');
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
382
app/Http/Controllers/Api/BigDataResumeController.php
Normal file
382
app/Http/Controllers/Api/BigDataResumeController.php
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportDirectorExport;
|
||||||
|
use App\Exports\ReportPaymentRecapExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\BigdataResumeResource;
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use App\Models\DataSetting;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class BigDataResumeController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$filterDate = $request->get("filterByDate");
|
||||||
|
|
||||||
|
if (!$filterDate || $filterDate === "latest") {
|
||||||
|
$big_data_resume = BigdataResume::where('year', 'leader')->latest()->first();
|
||||||
|
if (!$big_data_resume) {
|
||||||
|
return $this->response_empty_resume();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$big_data_resume = BigdataResume::where('year', 'leader')
|
||||||
|
->whereDate('created_at', $filterDate)
|
||||||
|
->orderBy('id', 'desc')
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$big_data_resume) {
|
||||||
|
return $this->response_empty_resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$data_settings = DataSetting::all();
|
||||||
|
if($data_settings->isEmpty()){
|
||||||
|
return response()->json(['message' => 'No data setting found']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanNumber($value) {
|
||||||
|
return floatval(str_replace('.', '', $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
$target_pad = floatval(optional($data_settings->where('key', 'TARGET_PAD')->first())->value);
|
||||||
|
$realisasi_terbit_pbg_sum = cleanNumber(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_SUM')->first())->value);
|
||||||
|
$realisasi_terbit_pbg_count = cleanNumber(optional($data_settings->where('key', 'REALISASI_TERBIT_PBG_COUNT')->first())->value);
|
||||||
|
$menunggu_klik_dpmptsp_sum = cleanNumber(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_SUM')->first())->value);
|
||||||
|
$menunggu_klik_dpmptsp_count = cleanNumber(optional($data_settings->where('key', 'MENUNGGU_KLIK_DPMPTSP_COUNT')->first())->value);
|
||||||
|
$proses_dinas_teknis_sum = cleanNumber(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_SUM')->first())->value);
|
||||||
|
$proses_dinas_teknis_count = cleanNumber(optional($data_settings->where('key', 'PROSES_DINAS_TEKNIS_COUNT')->first())->value);
|
||||||
|
|
||||||
|
$tata_ruang = $big_data_resume->spatial_sum;
|
||||||
|
$kekurangan_potensi = $target_pad - $big_data_resume->potention_sum;
|
||||||
|
|
||||||
|
// percentage kekurangan potensi
|
||||||
|
$kekurangan_potensi_percentage = $target_pad > 0 && $target_pad > 0
|
||||||
|
? round(($kekurangan_potensi / $target_pad) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage total potensi
|
||||||
|
$total_potensi_percentage = $big_data_resume->potention_sum > 0 && $target_pad > 0
|
||||||
|
? round(($big_data_resume->potention_sum / $target_pad) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage verified document
|
||||||
|
$verified_percentage = $big_data_resume->verified_sum > 0 && $big_data_resume->potention_sum > 0
|
||||||
|
? round(($big_data_resume->verified_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage non-verified document
|
||||||
|
$non_verified_percentage = $big_data_resume->non_verified_sum > 0 && $big_data_resume->potention_sum > 0
|
||||||
|
? round(($big_data_resume->non_verified_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage business document
|
||||||
|
$business_percentage = $big_data_resume->business_sum > 0 && $big_data_resume->non_verified_sum > 0
|
||||||
|
? round(($big_data_resume->business_sum / $big_data_resume->non_verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage non-business document
|
||||||
|
$non_business_percentage = $big_data_resume->non_business_sum > 0 && $big_data_resume->potention_sum > 0
|
||||||
|
? round(($big_data_resume->non_business_sum / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage tata ruang
|
||||||
|
$tata_ruang_percentage = $tata_ruang > 0 && $big_data_resume->potention_sum > 0
|
||||||
|
? round(($tata_ruang / $big_data_resume->potention_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage realisasi terbit pbg
|
||||||
|
$realisasi_terbit_percentage = $big_data_resume->verified_sum > 0 && $realisasi_terbit_pbg_sum > 0
|
||||||
|
? round(($realisasi_terbit_pbg_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage menunggu klik dpmptsp
|
||||||
|
$menunggu_klik_dpmptsp_percentage = $big_data_resume->verified_sum > 0 && $menunggu_klik_dpmptsp_sum > 0
|
||||||
|
? round(($menunggu_klik_dpmptsp_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
// percentage proses_dinas_teknis
|
||||||
|
$proses_dinas_teknis_percentage = $big_data_resume->verified_sum > 0 && $proses_dinas_teknis_sum > 0
|
||||||
|
? round(($proses_dinas_teknis_sum / $big_data_resume->verified_sum) * 100, 2) : 0;
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'target_pad' => [
|
||||||
|
'sum' => $target_pad,
|
||||||
|
'percentage' => 100,
|
||||||
|
],
|
||||||
|
'tata_ruang' => [
|
||||||
|
'sum' => $big_data_resume->spatial_sum,
|
||||||
|
'count' => $big_data_resume->spatial_count,
|
||||||
|
'percentage' => $tata_ruang_percentage,
|
||||||
|
],
|
||||||
|
'kekurangan_potensi' => [
|
||||||
|
'sum' => $kekurangan_potensi,
|
||||||
|
'percentage' => $kekurangan_potensi_percentage
|
||||||
|
],
|
||||||
|
'total_potensi' => [
|
||||||
|
'sum' => (float) $big_data_resume->potention_sum,
|
||||||
|
'count' => $big_data_resume->potention_count,
|
||||||
|
'percentage' => $total_potensi_percentage
|
||||||
|
],
|
||||||
|
'verified_document' => [
|
||||||
|
'sum' => (float) $big_data_resume->verified_sum,
|
||||||
|
'count' => $big_data_resume->verified_count,
|
||||||
|
'percentage' => $verified_percentage
|
||||||
|
],
|
||||||
|
'non_verified_document' => [
|
||||||
|
'sum' => (float) $big_data_resume->non_verified_sum,
|
||||||
|
'count' => $big_data_resume->non_verified_count,
|
||||||
|
'percentage' => $non_verified_percentage
|
||||||
|
],
|
||||||
|
'business_document' => [
|
||||||
|
'sum' => (float) $big_data_resume->business_sum,
|
||||||
|
'count' => $big_data_resume->business_count,
|
||||||
|
'percentage' => $business_percentage
|
||||||
|
],
|
||||||
|
'non_business_document' => [
|
||||||
|
'sum' => (float) $big_data_resume->non_business_sum,
|
||||||
|
'count' => $big_data_resume->non_business_count,
|
||||||
|
'percentage' => $non_business_percentage
|
||||||
|
],
|
||||||
|
'realisasi_terbit' => [
|
||||||
|
'sum' => $realisasi_terbit_pbg_sum,
|
||||||
|
'count' => $realisasi_terbit_pbg_count,
|
||||||
|
'percentage' => $realisasi_terbit_percentage
|
||||||
|
],
|
||||||
|
'menunggu_klik_dpmptsp' => [
|
||||||
|
'sum' => $menunggu_klik_dpmptsp_sum,
|
||||||
|
'count' => $menunggu_klik_dpmptsp_count,
|
||||||
|
'percentage' => $menunggu_klik_dpmptsp_percentage
|
||||||
|
],
|
||||||
|
'proses_dinas_teknis' => [
|
||||||
|
'sum' => $proses_dinas_teknis_sum,
|
||||||
|
'count' => $proses_dinas_teknis_count,
|
||||||
|
'percentage' => $proses_dinas_teknis_percentage
|
||||||
|
]
|
||||||
|
];
|
||||||
|
return response()->json($result);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function bigdata_report(Request $request){
|
||||||
|
try{
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if($request->filled('search')){
|
||||||
|
$query->where('year', 'LIKE', '%'.$request->input('search').'%');
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $query->paginate(config('app.paginate_per_page', 50));
|
||||||
|
return BigdataResumeResource::collection($query)->response()->getData(true);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function payment_recaps(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
|
||||||
|
$query->whereBetween('created_at', [$startDate, $endDate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $query->paginate(50);
|
||||||
|
|
||||||
|
// Restructure response
|
||||||
|
$transformedData = [];
|
||||||
|
|
||||||
|
foreach ($data as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$transformedData[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'category' => $key,
|
||||||
|
'nominal' => $value,
|
||||||
|
'created_at' => $createdAt,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => $transformedData, // Flat array
|
||||||
|
'pagination' => [
|
||||||
|
'total' => count($transformedData),
|
||||||
|
'per_page' => $data->perPage(),
|
||||||
|
'current_page' => $data->currentPage(),
|
||||||
|
'last_page' => $data->lastPage(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Error when fetching data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_excel_payment_recaps(Request $request)
|
||||||
|
{
|
||||||
|
$startDate = null;
|
||||||
|
$endDate = null;
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Excel::download(new ReportPaymentRecapExport($startDate, $endDate), 'laporan-rekap-pembayaran.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_pdf_payment_recaps(Request $request){
|
||||||
|
$query = BigdataResume::query()->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('start_date') && $request->filled('end_date')) {
|
||||||
|
$startDate = Carbon::parse($request->input('start_date'))->startOfDay();
|
||||||
|
$endDate = Carbon::parse($request->input('end_date'))->endOfDay();
|
||||||
|
|
||||||
|
$query->whereBetween('created_at', [$startDate, $endDate]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $query->get();
|
||||||
|
|
||||||
|
// Define category mapping
|
||||||
|
$categoryMap = [
|
||||||
|
'potention_sum' => 'Potensi',
|
||||||
|
'non_verified_sum' => 'Belum Terverifikasi',
|
||||||
|
'verified_sum' => 'Terverifikasi',
|
||||||
|
'business_sum' => 'Usaha',
|
||||||
|
'non_business_sum' => 'Non Usaha',
|
||||||
|
'spatial_sum' => 'Tata Ruang',
|
||||||
|
'waiting_click_dpmptsp_sum' => 'Menunggu Klik DPMPTSP',
|
||||||
|
'issuance_realization_pbg_sum' => 'Realisasi Terbit PBG',
|
||||||
|
'process_in_technical_office_sum' => 'Proses Di Dinas Teknis',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Restructure response
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$createdAt = $item->created_at;
|
||||||
|
$id = $item->id;
|
||||||
|
|
||||||
|
foreach ($item->toArray() as $key => $value) {
|
||||||
|
// Only include columns with "sum" in their names
|
||||||
|
if (strpos($key, 'sum') !== false) {
|
||||||
|
$data[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'category' => $categoryMap[$key] ?? $key, // Map category
|
||||||
|
'nominal' => $value, // Format number
|
||||||
|
'created_at' => $createdAt->format('Y-m-d H:i:s'), // Format date
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdf = Pdf::loadView('exports.payment_recaps_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-rekap-pembayaran.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function export_excel_report_director(){
|
||||||
|
return Excel::download(new ReportDirectorExport, 'laporan-pimpinan.xlsx');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_pdf_report_director(){
|
||||||
|
$data = BigdataResume::select(
|
||||||
|
'potention_count',
|
||||||
|
'potention_sum',
|
||||||
|
'non_verified_count',
|
||||||
|
'non_verified_sum',
|
||||||
|
'verified_count',
|
||||||
|
'verified_sum',
|
||||||
|
'business_count',
|
||||||
|
'business_sum',
|
||||||
|
'non_business_count',
|
||||||
|
'non_business_sum',
|
||||||
|
'spatial_count',
|
||||||
|
'spatial_sum',
|
||||||
|
'waiting_click_dpmptsp_count',
|
||||||
|
'waiting_click_dpmptsp_sum',
|
||||||
|
'issuance_realization_pbg_count',
|
||||||
|
'issuance_realization_pbg_sum',
|
||||||
|
'process_in_technical_office_count',
|
||||||
|
'process_in_technical_office_sum',
|
||||||
|
'year',
|
||||||
|
'created_at'
|
||||||
|
)->orderBy('id', 'desc')->get();
|
||||||
|
$pdf = Pdf::loadView('exports.director_report', compact('data'))->setPaper('a4', 'landscape');
|
||||||
|
return $pdf->download('laporan-pimpinan.pdf');
|
||||||
|
}
|
||||||
|
private function response_empty_resume(){
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
107
app/Http/Controllers/Api/BusinessOrIndustriesController.php
Normal file
107
app/Http/Controllers/Api/BusinessOrIndustriesController.php
Normal 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(config('app.paginate_per_page', 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
117
app/Http/Controllers/Api/ChatbotController.php
Normal file
117
app/Http/Controllers/Api/ChatbotController.php
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Services\OpenAIService;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class ChatbotController extends Controller
|
||||||
|
{
|
||||||
|
protected $openAIService;
|
||||||
|
|
||||||
|
public function __construct(OpenAIService $openAIService)
|
||||||
|
{
|
||||||
|
$this->openAIService = $openAIService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateText(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'tab_active' => 'required|string',
|
||||||
|
'prompt' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tab_active = $request->input('tab_active');
|
||||||
|
$main_content = match ($tab_active) {
|
||||||
|
"count-retribusi" => "RETRIBUTION",
|
||||||
|
"document-validation" => "DOCUMENT VALIDATION",
|
||||||
|
"data-information" => "DATA SUMMARY",
|
||||||
|
default => "UNKNOWN",
|
||||||
|
};
|
||||||
|
|
||||||
|
$chatHistory = $request->input('chatHistory');
|
||||||
|
Log::info('Chat history sebelum disimpan:', ['history' => $chatHistory]);
|
||||||
|
|
||||||
|
if ($main_content === "UNKNOWN") {
|
||||||
|
return response()->json(['response' => 'Invalid tab_active value.'], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// info($main_content);
|
||||||
|
|
||||||
|
$queryResponse = $this->openAIService->generateQueryBasedMainContent($request->input('prompt'), $main_content, $chatHistory);
|
||||||
|
|
||||||
|
if (str_contains($queryResponse, 'tidak relevan') || str_contains($queryResponse, 'tidak valid') || str_starts_with($queryResponse, 'Prompt')) {
|
||||||
|
return response()->json(['response' => $queryResponse], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$formattedResultQuery = "[]";
|
||||||
|
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
||||||
|
$resultQuery = DB::select($queryResponse);
|
||||||
|
$formattedResultQuery = json_encode($resultQuery, JSON_PRETTY_PRINT);
|
||||||
|
info($formattedResultQuery);
|
||||||
|
|
||||||
|
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
||||||
|
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
||||||
|
return response()->json(['response' => $finalGeneratedText, 'nlpResponse' => $queryResponse]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function mainGenerateText(Request $request)
|
||||||
|
{
|
||||||
|
// Log hanya data yang relevan
|
||||||
|
info("Received prompt: " . $request->input('prompt'));
|
||||||
|
|
||||||
|
// Validasi input
|
||||||
|
$request->validate([
|
||||||
|
'prompt' => 'required|string',
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Panggil service untuk generate text
|
||||||
|
$classifyResponse = $this->openAIService->classifyMainGenerateText($request->input('prompt'));
|
||||||
|
info($classifyResponse);
|
||||||
|
|
||||||
|
// Pastikan hasil klasifikasi valid sebelum melanjutkan
|
||||||
|
$validCategories = [
|
||||||
|
'reklame', 'business_or_industries', 'customers',
|
||||||
|
'pbg', 'retribusi', 'spatial_plannings',
|
||||||
|
'tourisms', 'umkms'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array($classifyResponse, $validCategories)) {
|
||||||
|
return response()->json([
|
||||||
|
'error' => ''
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chatHistory = $request->input('chatHistory');
|
||||||
|
Log::info('Chat history sebelum disimpan:', ['history' => $chatHistory]);
|
||||||
|
|
||||||
|
$queryResponse = $this->openAIService->createMainQuery($classifyResponse, $request->input('prompt'), $chatHistory);
|
||||||
|
info($queryResponse);
|
||||||
|
|
||||||
|
$formattedResultQuery = "[]";
|
||||||
|
|
||||||
|
$queryResponse = str_replace(['```sql', '```'], '', $queryResponse);
|
||||||
|
$queryResult = DB::select($queryResponse);
|
||||||
|
|
||||||
|
$formattedResultQuery = json_encode($queryResult, JSON_PRETTY_PRINT);
|
||||||
|
|
||||||
|
$nlpResult = $this->openAIService->generateNLPFromQuery($request->input('prompt'), $formattedResultQuery);
|
||||||
|
$finalGeneratedText =$this->openAIService->generateFinalText($nlpResult);
|
||||||
|
|
||||||
|
return response()->json(['response' => $finalGeneratedText, 'nlpResponse' => $queryResponse]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Tangani error dan log exception
|
||||||
|
\Log::error("Error generating text: " . $e->getMessage());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'error' => ''
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
130
app/Http/Controllers/Api/CustomersController.php
Normal file
130
app/Http/Controllers/Api/CustomersController.php
Normal 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(config('app.paginate_per_page', 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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');
|
||||||
|
|
||||||
|
$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])
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$query->where("pbg_task.function_type", "LIKE", "sebagai tempat usaha%");
|
$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();
|
->first();
|
||||||
$taskCount = $businessData->task_count;
|
});
|
||||||
$taskTotal = $businessData->total_retribution;
|
|
||||||
$result = [
|
$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){
|
||||||
|
|||||||
104
app/Http/Controllers/Api/DataSettingController.php
Normal file
104
app/Http/Controllers/Api/DataSettingController.php
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ class GlobalSettingsController extends Controller
|
|||||||
try {
|
try {
|
||||||
$data = GlobalSetting::create($request->validated());
|
$data = GlobalSetting::create($request->validated());
|
||||||
return new GlobalSettingResource($data);
|
return new GlobalSettingResource($data);
|
||||||
} catch (\Exception $e) {
|
} catch (Exception $e) {
|
||||||
return $this->resError($e->getMessage(), null, $e->getCode());
|
return $this->resError($e->getMessage(), null, $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
app/Http/Controllers/Api/GoogleSheetController.php
Normal file
43
app/Http/Controllers/Api/GoogleSheetController.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GoogleSheetController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
91
app/Http/Controllers/Api/GrowthReportAPIController.php
Normal file
91
app/Http/Controllers/Api/GrowthReportAPIController.php
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\BigdataResume;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class GrowthReportAPIController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
// Get current date
|
||||||
|
$today = Carbon::today();
|
||||||
|
|
||||||
|
// Define default range: 1 month back from today
|
||||||
|
$defaultStart = $today->copy()->subMonth();
|
||||||
|
$defaultEnd = $today;
|
||||||
|
|
||||||
|
// Use request values if provided, else use defaults
|
||||||
|
// $startDate = $request->input('start_date', $defaultStart->toDateString());
|
||||||
|
// $endDate = $request->input('end_date', $defaultEnd->toDateString());
|
||||||
|
|
||||||
|
// Optional year filter (used if specified)
|
||||||
|
$year = $request->input('year', now()->year);
|
||||||
|
|
||||||
|
// $query = BigdataResume::selectRaw("
|
||||||
|
// DATE(created_at) as date,
|
||||||
|
// SUM(potention_sum) as potention_sum,
|
||||||
|
// SUM(verified_sum) as verified_sum,
|
||||||
|
// SUM(non_verified_sum) as non_verified_sum
|
||||||
|
// ")
|
||||||
|
// ->whereBetween('created_at', [$startDate, $endDate]);
|
||||||
|
$query = BigdataResume::selectRaw("
|
||||||
|
DATE(created_at) as date,
|
||||||
|
SUM(potention_sum) as potention_sum,
|
||||||
|
SUM(verified_sum) as verified_sum,
|
||||||
|
SUM(non_verified_sum) as non_verified_sum
|
||||||
|
");
|
||||||
|
|
||||||
|
$query->whereNotNull('year')
|
||||||
|
->where('year', '!=', 'all');
|
||||||
|
|
||||||
|
$data = $query->groupBy(DB::raw('DATE(created_at)'))
|
||||||
|
->orderBy(DB::raw('DATE(created_at)'))
|
||||||
|
->get()
|
||||||
|
->map(function ($item) {
|
||||||
|
$item->date = Carbon::parse($item->date)->format('d M Y');
|
||||||
|
return $item;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response()->json($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ class ImportDatasourceController extends Controller
|
|||||||
$search = $request->get("search");
|
$search = $request->get("search");
|
||||||
$query->where('status', 'like', "%".$search."%");
|
$query->where('status', 'like', "%".$search."%");
|
||||||
}
|
}
|
||||||
return ImportDatasourceResource::collection($query->paginate());
|
return ImportDatasourceResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkImportDatasource(){
|
public function checkImportDatasource(){
|
||||||
|
|||||||
38
app/Http/Controllers/Api/LackOfPotentialController.php
Normal file
38
app/Http/Controllers/Api/LackOfPotentialController.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Advertisement;
|
||||||
|
use App\Models\Customer;
|
||||||
|
use App\Models\SpatialPlanning;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
|
||||||
|
class LackOfPotentialController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
public function count_lack_of_potential(){
|
||||||
|
try{
|
||||||
|
$total_reklame = Advertisement::count();
|
||||||
|
$total_pdam = Customer::count();
|
||||||
|
$total_tata_ruang = SpatialPlanning::count();
|
||||||
|
$total_tata_ruang_usaha = SpatialPlanning::where('building_function','like', '%usaha%')->count();
|
||||||
|
$total_tata_ruang_non_usaha = SpatialPlanning::where('building_function','like', '%hunian%')->count();
|
||||||
|
$data_report_tourism = TourismBasedKBLI::all();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'total_reklame' => $total_reklame,
|
||||||
|
'total_pdam' => $total_pdam,
|
||||||
|
'total_tata_ruang' => $total_tata_ruang,
|
||||||
|
'total_tata_ruang_usaha' => $total_tata_ruang_usaha,
|
||||||
|
'total_tata_ruang_non_usaha' => $total_tata_ruang_non_usaha,
|
||||||
|
'data_report' => $data_report_tourism,
|
||||||
|
], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Error: '.$e->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
110
app/Http/Controllers/Api/MenusController.php
Normal file
110
app/Http/Controllers/Api/MenusController.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?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(config('app.paginate_per_page', 50)));
|
||||||
|
return MenuResource::collection($query->paginate(config('app.paginate_per_page',50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
109
app/Http/Controllers/Api/PbgTaskAttachmentsController.php
Normal file
109
app/Http/Controllers/Api/PbgTaskAttachmentsController.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTaskAttachment;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class PbgTaskAttachmentsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request, $pbg_task_id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$request->validate([
|
||||||
|
'file' => 'required|file|mimes:jpg,png,pdf|max:5120',
|
||||||
|
'pbg_type' => 'string'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$attachment = PbgTaskAttachment::create([
|
||||||
|
'pbg_task_id' => $pbg_task_id,
|
||||||
|
'file_name' => $request->file('file')->getClientOriginalName(),
|
||||||
|
'file_path' => '', // empty path initially
|
||||||
|
'pbg_type' => $request->pbg_type == 'bukti_bayar' ? 'bukti_bayar' : 'berita_acara'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$file = $request->file('file');
|
||||||
|
$path = $file->store("uploads/pbg-tasks/{$pbg_task_id}/{$attachment->id}", "public");
|
||||||
|
|
||||||
|
$attachment->update([
|
||||||
|
'file_path' => $path,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'File uploaded successfully.',
|
||||||
|
'attachment' => [
|
||||||
|
'id' => $attachment->id,
|
||||||
|
'file_name' => $attachment->file_name,
|
||||||
|
'file_url' => Storage::url($attachment->file_path),
|
||||||
|
'pbg_type' => $attachment->pbg_type
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
\Log::error($e->getMessage());
|
||||||
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
|
"message" => $e->getTraceAsString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function download(string $id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$data = PbgTaskAttachment::findOrFail($id);
|
||||||
|
$filePath = $data->file_path; // already relative to 'public' disk
|
||||||
|
|
||||||
|
if (!Storage::disk('public')->exists($filePath)) {
|
||||||
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
|
"message" => "File not found on server"
|
||||||
|
], Response::HTTP_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Storage::disk('public')->download($filePath, $data->file_name);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
|
"message" => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
195
app/Http/Controllers/Api/PbgTaskController.php
Normal file
195
app/Http/Controllers/Api/PbgTaskController.php
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Enums\ImportDatasourceStatus;
|
||||||
|
use App\Enums\PbgTaskApplicationTypes;
|
||||||
|
use App\Enums\PbgTaskStatus;
|
||||||
|
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;
|
||||||
|
use Illuminate\Validation\Rules\Enum;
|
||||||
|
|
||||||
|
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 $task_uuid)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$pbg_task = PbgTask::where('uuid',$task_uuid)->first();
|
||||||
|
|
||||||
|
if(!$pbg_task){
|
||||||
|
return response()->json([
|
||||||
|
"success"=> false,
|
||||||
|
"message"=> "Data PBG Task tidak ditemukan",
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$validated = $request->validate([
|
||||||
|
'name' => 'required|string|max:255',
|
||||||
|
'owner_name' => 'required|string|max:255',
|
||||||
|
'application_type' => ['nullable', new Enum(PbgTaskApplicationTypes::class)],
|
||||||
|
'condition' => 'required|string|max:255',
|
||||||
|
'registration_number' => 'required|string|max:255',
|
||||||
|
'document_number' => 'required|string|max:255',
|
||||||
|
'status' => ['nullable', new Enum(PbgTaskStatus::class)],
|
||||||
|
'address' => 'required|string|max:255',
|
||||||
|
'slf_status_name' => 'nullable|string|max:255',
|
||||||
|
'function_type' => 'required|string|max:255',
|
||||||
|
'consultation_type' => 'required|string|max:255',
|
||||||
|
'due_date' => 'nullable|date|after_or_equal:today',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$statusLabel = $validated['status'] !== null ? PbgTaskStatus::getLabel($validated['status']) : null;
|
||||||
|
$applicationLabel = $validated['application_type'] !== null ? PbgTaskApplicationTypes::getLabel($validated['application_type']) : null;
|
||||||
|
|
||||||
|
$pbg_task->update([
|
||||||
|
'name' => $validated['name'],
|
||||||
|
'owner_name' => $validated['owner_name'],
|
||||||
|
'application_type' => $validated['application_type'],
|
||||||
|
'application_type_name' => $applicationLabel, // Automatically set application_type_name
|
||||||
|
'condition' => $validated['condition'],
|
||||||
|
'registration_number' => $validated['registration_number'],
|
||||||
|
'document_number' => $validated['document_number'],
|
||||||
|
'status' => $validated['status'],
|
||||||
|
'status_name' => $statusLabel, // Automatically set status_name
|
||||||
|
'address' => $validated['address'],
|
||||||
|
'slf_status_name' => $validated['slf_status_name'],
|
||||||
|
'function_type' => $validated['function_type'],
|
||||||
|
'consultation_type' => $validated['consultation_type'],
|
||||||
|
'due_date' => $validated['due_date'],
|
||||||
|
]);
|
||||||
|
return response()->json([
|
||||||
|
"success"=> true,
|
||||||
|
"message"=> "Data berhasil diubah",
|
||||||
|
"data"=> $pbg_task
|
||||||
|
]);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json([
|
||||||
|
"success"=> false,
|
||||||
|
"message"=> $e->getMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function validatePbgTask(Request $request){
|
||||||
|
return $request->validate([
|
||||||
|
"uuid" => $request->input("step1Form.uuid"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
61
app/Http/Controllers/Api/PbgTaskGoogleSheetsController.php
Normal file
61
app/Http/Controllers/Api/PbgTaskGoogleSheetsController.php
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\PbgTaskGoogleSheetResource;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PbgTaskGoogleSheetsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$query = PbgTaskGoogleSheet::query()->orderBy('id', 'desc');
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$query->where('no_registrasi', 'like', "%{$request->get('search')}%");
|
||||||
|
}
|
||||||
|
return PbgTaskGoogleSheetResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$data = PbgTaskGoogleSheet::find($id);
|
||||||
|
$data->delete();
|
||||||
|
return response()->json(['message' => 'Data deleted successfully'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return response()->json(['message' => 'Failed to delete data'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
app/Http/Controllers/Api/ReportPbgPtspController.php
Normal file
29
app/Http/Controllers/Api/ReportPbgPtspController.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportPbgPtspExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ReportPbgPtspController extends Controller
|
||||||
|
{
|
||||||
|
public function export_excel(){
|
||||||
|
return Excel::download(new ReportPbgPtspExport, 'laporan-ptsp.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf(){
|
||||||
|
$data = PbgTask::select(
|
||||||
|
'status',
|
||||||
|
'status_name', // Keeping this column
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->get();
|
||||||
|
$pdf = Pdf::loadView('exports.ptsp_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-ptsp.pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/Http/Controllers/Api/ReportTourismsController.php
Normal file
22
app/Http/Controllers/Api/ReportTourismsController.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\ReportTourismExport;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
|
class ReportTourismsController extends Controller
|
||||||
|
{
|
||||||
|
public function export_excel(){
|
||||||
|
return Excel::download(new ReportTourismExport, 'laporan-pariwisata.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf(){
|
||||||
|
$data = TourismBasedKBLI::all();
|
||||||
|
$pdf = Pdf::loadView('exports.tourisms_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-pariwisata.pdf');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Exports\DistrictPaymentRecapExport;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Resources\RequestAssignmentResouce;
|
use App\Http\Resources\RequestAssignmentResouce;
|
||||||
use App\Models\PbgTask;
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
|
||||||
class RequestAssignmentController extends Controller
|
class RequestAssignmentController extends Controller
|
||||||
{
|
{
|
||||||
@@ -14,13 +21,112 @@ class RequestAssignmentController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$query = PbgTask::query();
|
$query = PbgTask::with([
|
||||||
if($request->has('search') && !empty($request->get("search"))){
|
'attachments' => function ($q) {
|
||||||
$query->where('name', 'LIKE', '%'.$request->get('search').'%');
|
$q->whereIn('pbg_type', ['berita_acara', 'bukti_bayar']);
|
||||||
|
},
|
||||||
|
'googleSheet'
|
||||||
|
])->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->has('filter') && !empty($request->get('filter'))) {
|
||||||
|
$filter = strtolower($request->get('filter'));
|
||||||
|
|
||||||
|
switch ($filter) {
|
||||||
|
case 'non-business':
|
||||||
|
$query->whereRaw("LOWER(function_type) != ?", ['sebagai tempat usaha'])->orWhereNull('function_type');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'business':
|
||||||
|
$query->whereRaw("LOWER(function_type) = ?", ['sebagai tempat usaha']);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'verified':
|
||||||
|
$query->whereHas('googleSheet', function ($q) {
|
||||||
|
$q->whereRaw("LOWER(status_verifikasi) = ?", ['selesai verifikasi']);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'non-verified':
|
||||||
|
$query->where(function ($q) {
|
||||||
|
$q->whereDoesntHave('googleSheet')
|
||||||
|
->orWhereHas('googleSheet', function ($q2) {
|
||||||
|
$q2->whereRaw("LOWER(status_verifikasi) != ?", ['selesai verifikasi'])->orWhereNull('status_verifikasi');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('search') && !empty($request->get("search"))) {
|
||||||
|
$search = $request->get('search');
|
||||||
|
$query->where(function ($q) use ($search) {
|
||||||
|
$q->where('name', 'LIKE', "%$search%")
|
||||||
|
->orWhere('registration_number', 'LIKE', "%$search%")
|
||||||
|
->orWhere('document_number', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return RequestAssignmentResouce::collection($query->paginate());
|
return RequestAssignmentResouce::collection($query->paginate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function report_payment_recaps(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Query dengan group by kecamatan dan sum nilai_retribusi_keseluruhan_simbg
|
||||||
|
$query = PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
// Return hasil dalam JSON format
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $query
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export_excel_district_payment_recaps(){
|
||||||
|
return Excel::download(new DistrictPaymentRecapExport, 'laporan-rekap-data-pembayaran.xlsx');
|
||||||
|
}
|
||||||
|
public function export_pdf_district_payment_recaps(){
|
||||||
|
$data = PbgTaskGoogleSheet::select(
|
||||||
|
'kecamatan',
|
||||||
|
DB::raw('SUM(nilai_retribusi_keseluruhan_simbg) as total')
|
||||||
|
)
|
||||||
|
->groupBy('kecamatan')->get();
|
||||||
|
$pdf = Pdf::loadView('exports.district_payment_report', compact('data'));
|
||||||
|
return $pdf->download('laporan-rekap-data-pembayaran.pdf');
|
||||||
|
}
|
||||||
|
public function report_pbg_ptsp()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Query dengan group by status dan count total per status
|
||||||
|
$query = PbgTask::select(
|
||||||
|
'status',
|
||||||
|
'status_name',
|
||||||
|
DB::raw('COUNT(*) as total')
|
||||||
|
)
|
||||||
|
->groupBy('status', 'status_name')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
// Return hasil dalam JSON format
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $query
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error($e->getMessage());
|
||||||
|
return response()->json(['message' => 'Terjadi kesalahan: ' . $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*/
|
*/
|
||||||
|
|||||||
91
app/Http/Controllers/Api/RolesController.php
Normal file
91
app/Http/Controllers/Api/RolesController.php
Normal 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(config('app.paginate_per_page', 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,16 @@ namespace App\Http\Controllers\Api;
|
|||||||
|
|
||||||
use App\Enums\ImportDatasourceStatus;
|
use App\Enums\ImportDatasourceStatus;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Jobs\RetrySyncronizeJob;
|
||||||
|
use App\Jobs\ScrapingDataJob;
|
||||||
|
use App\Jobs\SyncronizeSIMBG;
|
||||||
use App\Models\ImportDatasource;
|
use App\Models\ImportDatasource;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
|
use App\Services\ServiceTokenSIMBG;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use App\Services\ServiceGoogleSheet;
|
||||||
|
use App\Services\ServicePbgTask;
|
||||||
|
use App\Services\ServiceTabPbgTask;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -22,40 +30,33 @@ class ScrapingController extends Controller
|
|||||||
return $this->resError("Failed to execute while processing another scraping");
|
return $this->resError("Failed to execute while processing another scraping");
|
||||||
}
|
}
|
||||||
|
|
||||||
// run service artisan command
|
// use ole schema synchronization
|
||||||
Artisan::call("app:execute-scraping");
|
// dispatch(new SyncronizeSIMBG());
|
||||||
return $this->resSuccess("Success execute scraping service please wait");
|
|
||||||
|
// use new schema synchronization
|
||||||
|
dispatch(new ScrapingDataJob());
|
||||||
|
return $this->resSuccess(["message" => "Success execute scraping service on background, check status for more"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function retry_syncjob(string $import_datasource_id){
|
||||||
* Store a newly created resource in storage.
|
try{
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
$import_datasource = ImportDatasource::find($import_datasource_id);
|
||||||
{
|
if(!$import_datasource){
|
||||||
//
|
return $this->resError("Invalid import datasource id", null, 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
dispatch(new RetrySyncronizeJob($import_datasource->id));
|
||||||
* Display the specified resource.
|
return response()->json([
|
||||||
*/
|
"success" => true,
|
||||||
public function show(string $id)
|
"message" => "Retrying scrape job on background, check status for more"
|
||||||
{
|
]);
|
||||||
//
|
}catch(\Exception $e){
|
||||||
}
|
return response()->json([
|
||||||
|
"success" => false,
|
||||||
/**
|
"message" => "Failed to retry sync job",
|
||||||
* Update the specified resource in storage.
|
"error" => $e->getMessage()
|
||||||
*/
|
]);
|
||||||
public function update(Request $request, string $id)
|
}
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
146
app/Http/Controllers/Api/SpatialPlanningController.php
Normal file
146
app/Http/Controllers/Api/SpatialPlanningController.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
app/Http/Controllers/Api/TaskAssignmentsController.php
Normal file
64
app/Http/Controllers/Api/TaskAssignmentsController.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\TaskAssignmentsResource;
|
||||||
|
use App\Models\TaskAssignment;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TaskAssignmentsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request, $uuid)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$query = TaskAssignment::query()
|
||||||
|
->where('pbg_task_uid', $uuid)
|
||||||
|
->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$query->where('name', 'like', "%{$request->get('search')}%")
|
||||||
|
->orWhere('email', 'like', "%{$request->get('search')}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskAssignmentsResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
}catch(\Exception $exception){
|
||||||
|
return response()->json(['message' => $exception->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
169
app/Http/Controllers/Api/TourismController.php
Normal file
169
app/Http/Controllers/Api/TourismController.php
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Models\Tourism;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Requests\TourismRequest;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\TourismResource;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use App\Imports\TourismImport;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class TourismController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$perPage = $request->input('per_page', 15);
|
||||||
|
$search = $request->input('search', '');
|
||||||
|
|
||||||
|
$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->getCollection()->transform(function ($tourisms) {
|
||||||
|
$village = DB::table('villages')->where('village_code', $tourisms->village_code)->first();
|
||||||
|
$tourisms->village_name = $village ? $village->village_name : null;
|
||||||
|
|
||||||
|
$district = DB::table('districts')->where('district_code', $tourisms->district_code)->first();
|
||||||
|
$tourisms->district_name = $district ? $district->district_name : null;
|
||||||
|
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([
|
||||||
|
'data' => $data,
|
||||||
|
'meta' => [
|
||||||
|
'total' => $tourisms->total(),
|
||||||
|
'per_page' => $tourisms->perPage(),
|
||||||
|
'current_page' => $tourisms->currentPage(),
|
||||||
|
'last_page'=>$tourisms->lastPage(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(TourismRequest $request): Tourism
|
||||||
|
{
|
||||||
|
$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
|
||||||
|
*/
|
||||||
|
public function importFromFile(Request $request)
|
||||||
|
{
|
||||||
|
//Validasi file
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'file' => 'required|mimes:xlsx, xls|max:10240'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message'=>'File validation failed.',
|
||||||
|
'errors'=>$validator->errors()
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file = $request->file('file');
|
||||||
|
Excel::import(new TourismImport, $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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllLocation()
|
||||||
|
{
|
||||||
|
$locations = Tourism::whereNotNull('longitude')
|
||||||
|
->whereNotNull('latitude')
|
||||||
|
->select('project_name', 'longitude', 'latitude')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => $locations
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(Tourism $tourism): Tourism
|
||||||
|
{
|
||||||
|
return $tourism;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(TourismRequest $request, Tourism $tourism): Tourism
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Tourism $tourism): Response
|
||||||
|
{
|
||||||
|
$tourism->delete();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
206
app/Http/Controllers/Api/UmkmController.php
Normal file
206
app/Http/Controllers/Api/UmkmController.php
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use App\Models\Umkm;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Requests\UmkmRequest;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\UmkmResource;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use App\Imports\UmkmImport;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class UmkmController 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 = 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->getCollection()->transform(function ($umkm) {
|
||||||
|
$village = DB::table('villages')->where('village_code', $umkm->village_code)->first();
|
||||||
|
$umkm->village_name = $village ? $village->village_name : null;
|
||||||
|
|
||||||
|
$district = DB::table('districts')->where('district_code', $umkm->district_code)->first();
|
||||||
|
$umkm->district_name = $district ? $district->district_name : null;
|
||||||
|
|
||||||
|
$business_scale = DB::table('business_scale')->where('id', $umkm->business_scale_id)->first();
|
||||||
|
$umkm->business_scale = $business_scale ? $business_scale->business_scale : null;
|
||||||
|
|
||||||
|
$permit_status = DB::table('permit_status')->where('id', $umkm->permit_status_id)->first();
|
||||||
|
$umkm->permit_status = $permit_status ? $permit_status->permit_status : null;
|
||||||
|
|
||||||
|
$business_form = DB::table('business_form')->where('id', $umkm->business_form_id)->first();
|
||||||
|
$umkm->business_form = $business_form ? $business_form->business_form : null;
|
||||||
|
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([
|
||||||
|
'data' => $data,
|
||||||
|
'meta' => [
|
||||||
|
'total' => $umkm->total(),
|
||||||
|
'per_page' => $umkm->perPage(),
|
||||||
|
'current_page' => $umkm->currentPage(),
|
||||||
|
'last_page' => $umkm->lastPage(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(UmkmRequest $request): Umkm
|
||||||
|
{
|
||||||
|
info($request);
|
||||||
|
$data = $request->validated();
|
||||||
|
|
||||||
|
// Cari kode berdasarkan nama
|
||||||
|
$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');
|
||||||
|
$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_id'])->value('id');
|
||||||
|
$business_form_id = DB::table('business_form')->where('id', $data['business_form_id'])->value('id');
|
||||||
|
|
||||||
|
info($business_scale_id);
|
||||||
|
|
||||||
|
// Update data dengan kode yang ditemukan
|
||||||
|
$data['village_code'] = $village_code;
|
||||||
|
$data['district_code'] = $district_code;
|
||||||
|
$data['land_area'] = (double) $request['land_area'];
|
||||||
|
$data['business_scale_id'] = (int) $business_scale_id;
|
||||||
|
$data['permit_status_id'] = (int) $permit_status_id;
|
||||||
|
$data['business_form_id'] = (int) $business_form_id;
|
||||||
|
|
||||||
|
info($data);
|
||||||
|
|
||||||
|
// Simpan ke database
|
||||||
|
return Umkm::create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import advertisements from Excel or CSV.
|
||||||
|
*/
|
||||||
|
public function importFromFile(Request $request)
|
||||||
|
{
|
||||||
|
// Validasi file
|
||||||
|
$validator = Validator::make($request->all(), [
|
||||||
|
'file' => 'required|mimes:xlsx, xls|max:10240',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'File validation failed.',
|
||||||
|
'errors' => $validator->errors()
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Ambil file dari request
|
||||||
|
$file = $request->file('file');
|
||||||
|
|
||||||
|
// Menggunakan Laravel Excel untuk mengimpor file
|
||||||
|
Excel::import(new UmkmImport, $file);
|
||||||
|
|
||||||
|
// Jika sukses, kembalikan response sukses
|
||||||
|
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(Umkm $umkm): Umkm
|
||||||
|
{
|
||||||
|
return $umkm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(UmkmRequest $request, Umkm $umkm): Umkm
|
||||||
|
{
|
||||||
|
info($request);
|
||||||
|
$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');
|
||||||
|
$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_id'])->value('id');
|
||||||
|
$business_form_id = DB::table('business_form')->where('id', $data['business_form_id'])->value('id');
|
||||||
|
|
||||||
|
|
||||||
|
// Tambahkan village_code dan district_code ke data
|
||||||
|
$data['village_code'] = $village_code;
|
||||||
|
$data['district_code'] = $district_code;
|
||||||
|
$data['land_area'] = (double) $request['land_area'];
|
||||||
|
$data['business_scale_id'] = (int) $business_scale_id;
|
||||||
|
$data['permit_status_id'] = (int) $permit_status_id;
|
||||||
|
$data['business_form_id'] = (int) $business_form_id;
|
||||||
|
|
||||||
|
// Log data setelah transformasi
|
||||||
|
info($data);
|
||||||
|
|
||||||
|
$umkm->update($data);
|
||||||
|
|
||||||
|
return $umkm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Umkm $umkm): Response
|
||||||
|
{
|
||||||
|
$umkm->delete();
|
||||||
|
|
||||||
|
return response()->noContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function downloadExcelUmkm()
|
||||||
|
{
|
||||||
|
$filePath = public_path('templates/template_umkm.xlsx');
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,14 @@ 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;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
@@ -27,12 +30,72 @@ class UsersController extends Controller
|
|||||||
public function index(Request $request){
|
public function index(Request $request){
|
||||||
$query = User::query();
|
$query = User::query();
|
||||||
if($request->has('search') && !empty($request->get("search"))){
|
if($request->has('search') && !empty($request->get("search"))){
|
||||||
$query->where('name', 'LIKE', '%'.$request->get('search').'%');
|
$query->where('name', 'LIKE', '%'.$request->get('search').'%')
|
||||||
|
->orWhere('email', 'LIKE', '%'.$request->get('search').'%');
|
||||||
}
|
}
|
||||||
return UserResource::collection($query->paginate());
|
return UserResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
}
|
}
|
||||||
public function logout(Request $request){
|
public function logout(Request $request){
|
||||||
$request->user()->tokens()->delete();
|
$request->user()->tokens()->delete();
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id){
|
||||||
|
try{
|
||||||
|
$user = User::findOrFail($id);
|
||||||
|
DB::beginTransaction();
|
||||||
|
$user->delete();
|
||||||
|
DB::commit();
|
||||||
|
return response()->json(['message' => 'Successfully deleted'], 200);
|
||||||
|
}catch(\Exception $e){
|
||||||
|
Log::error('Failed to delete user: '. $e->getMessage());
|
||||||
|
return response()->json(['message' => 'Failed to delete user'],500);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
app/Http/Controllers/Approval/ApprovalController.php
Normal file
65
app/Http/Controllers/Approval/ApprovalController.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Approval;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ApprovalController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('approval.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
59
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Executable file → Normal file
59
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Executable file → Normal file
@@ -36,15 +36,68 @@ class AuthenticatedSessionController extends Controller
|
|||||||
// Ambil user yang sedang login
|
// Ambil user yang sedang login
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
||||||
// Buat token untuk API
|
// Hapus token lama jika ada
|
||||||
$token = $user->createToken(env('APP_KEY'))->plainTextToken;
|
$user->tokens()->delete();
|
||||||
|
|
||||||
// Simpan token di session (bisa digunakan di JavaScript)
|
// Buat token untuk API dengan scope dan expiration
|
||||||
|
$tokenName = config('app.name', 'Laravel') . '-' . $user->id . '-' . time();
|
||||||
|
|
||||||
|
// Token dengan scope (opsional)
|
||||||
|
$token = $user->createToken($tokenName, ['*'], now()->addDays(30))->plainTextToken;
|
||||||
|
|
||||||
|
// Simpan token di session untuk digunakan di frontend
|
||||||
session(['api_token' => $token]);
|
session(['api_token' => $token]);
|
||||||
|
|
||||||
return redirect()->intended(RouteServiceProvider::HOME);
|
return redirect()->intended(RouteServiceProvider::HOME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate API token for authenticated user
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function generateApiToken(Request $request)
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return response()->json(['error' => 'Unauthorized'], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete existing tokens
|
||||||
|
$user->tokens()->delete();
|
||||||
|
|
||||||
|
// Generate new token
|
||||||
|
$tokenName = config('app.name', 'Laravel') . '-' . $user->id . '-' . time();
|
||||||
|
$token = $user->createToken($tokenName, ['*'], now()->addDays(30))->plainTextToken;
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'token' => $token,
|
||||||
|
'token_type' => 'Bearer',
|
||||||
|
'expires_in' => 30 * 24 * 60 * 60, // 30 days in seconds
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke API token for authenticated user
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function revokeApiToken(Request $request)
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return response()->json(['error' => 'Unauthorized'], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->tokens()->delete();
|
||||||
|
|
||||||
|
return response()->json(['message' => 'All tokens revoked successfully']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy an authenticated session.
|
* Destroy an authenticated session.
|
||||||
*
|
*
|
||||||
|
|||||||
0
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ConfirmablePasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/EmailVerificationNotificationController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/EmailVerificationNotificationController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/EmailVerificationPromptController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/EmailVerificationPromptController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/NewPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/NewPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/PasswordResetLinkController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/PasswordResetLinkController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/RegisteredUserController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/RegisteredUserController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/VerifyEmailController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/VerifyEmailController.php
Executable file → Normal file
48
app/Http/Controllers/BigdataResumesController.php
Normal file
48
app/Http/Controllers/BigdataResumesController.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class BigdataResumesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('bigdata-resumes.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
43
app/Http/Controllers/BusinessOrIndustriesController.php
Normal file
43
app/Http/Controllers/BusinessOrIndustriesController.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\BusinessOrIndustry;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class BusinessOrIndustriesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('business-industries.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
return view("business-industries.create", compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id, Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$data = BusinessOrIndustry::findOrFail($id);
|
||||||
|
return view('business-industries.edit', compact('data', 'menuId'));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
app/Http/Controllers/Chatbot/ChatbotController.php
Normal file
17
app/Http/Controllers/Chatbot/ChatbotController.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Chatbot;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ChatbotController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Displya a listing of the resource
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('chatbot.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\ChatbotPimpinan;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ChatbotPimpinanController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('chatbot-pimpinan.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
49
app/Http/Controllers/Controller.php
Executable file → Normal file
49
app/Http/Controllers/Controller.php
Executable file → Normal file
@@ -2,7 +2,54 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
abstract class Controller
|
abstract class Controller
|
||||||
{
|
{
|
||||||
//
|
protected array $permissions = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
if (!Auth::check()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->setUserPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setUserPermissions()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$menus = $user->roles()
|
||||||
|
->with(['menus' => function ($query) {
|
||||||
|
$query->select('menus.id', 'menus.name')
|
||||||
|
->withPivot(['allow_show' ,'allow_create', 'allow_update', 'allow_destroy']);
|
||||||
|
}])
|
||||||
|
->get()
|
||||||
|
->pluck('menus')
|
||||||
|
->flatten()
|
||||||
|
->unique('id');
|
||||||
|
|
||||||
|
// Store permissions in an associative array
|
||||||
|
foreach ($menus as $menu) {
|
||||||
|
$this->permissions[$menu->id] = [
|
||||||
|
'allow_show' => $menu->pivot->allow_show ?? 0,
|
||||||
|
'allow_create' => $menu->pivot->allow_create ?? 0,
|
||||||
|
'allow_update' => $menu->pivot->allow_update ?? 0,
|
||||||
|
'allow_destroy' => $menu->pivot->allow_destroy ?? 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share permissions globally in views
|
||||||
|
view()->share('permissions', $this->permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPermissions()
|
||||||
|
{
|
||||||
|
return $this->permissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
app/Http/Controllers/CustomersController.php
Normal file
37
app/Http/Controllers/CustomersController.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Customer;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class CustomersController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('customers.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
|
}
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.create', compact('menuId'));
|
||||||
|
}
|
||||||
|
public function edit(Request $request, string $id)
|
||||||
|
{
|
||||||
|
$data = Customer::findOrFail($id);
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.edit', compact('data', 'menuId'));
|
||||||
|
}
|
||||||
|
public function upload(Request $request){
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
return view('customers.upload', compact('menuId'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,11 +3,31 @@
|
|||||||
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 App\Models\Menu;
|
||||||
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;
|
||||||
|
$menus = Menu::all();
|
||||||
|
return view('dashboards.bigdata', compact('latest_created', 'menus'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pbg()
|
||||||
|
{
|
||||||
|
return view('dashboards.pbg');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function leader()
|
||||||
|
{
|
||||||
|
$latest_import_datasource = ImportDatasource::latest()->first();
|
||||||
|
$latest_created = $latest_import_datasource ?
|
||||||
|
$latest_import_datasource->created_at->format("j F Y H:i:s") : null;
|
||||||
|
$menus = Menu::all();
|
||||||
|
return view('dashboards.leader', compact('latest_created', 'menus'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
18
app/Http/Controllers/Dashboards/PotentialsController.php
Normal file
18
app/Http/Controllers/Dashboards/PotentialsController.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Dashboards;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PotentialsController extends Controller
|
||||||
|
{
|
||||||
|
public function inside_system(){
|
||||||
|
$menus = Menu::all();
|
||||||
|
return view('dashboards.potentials.inside_system', compact('menus'));
|
||||||
|
}
|
||||||
|
public function outside_system(){
|
||||||
|
return view('dashboards.potentials.outside_system');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,15 +6,23 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Models\Advertisement;
|
use App\Models\Advertisement;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class AdvertisementController extends Controller
|
class AdvertisementController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('data.advertisements.index');
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('data.advertisements.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,8 +37,9 @@ class AdvertisementController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
$title = 'Advertisement';
|
$title = 'Advertisement';
|
||||||
$subtitle = 'Create Data';
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
@@ -47,14 +56,15 @@ class AdvertisementController extends Controller
|
|||||||
|
|
||||||
// $route = 'advertisements.create';
|
// $route = 'advertisements.create';
|
||||||
// info("AdvertisementController@edit diakses dengan ID: $title");
|
// info("AdvertisementController@edit diakses dengan ID: $title");
|
||||||
return view('data.advertisements.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.advertisements.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for editing the specified resource.
|
* Show the form for editing the specified resource.
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit(Request $request, $id)
|
||||||
{
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
info("AdvertisementController@edit diakses dengan ID: $id");
|
info("AdvertisementController@edit diakses dengan ID: $id");
|
||||||
$title = 'Advertisement';
|
$title = 'Advertisement';
|
||||||
$subtitle = 'Update Data';
|
$subtitle = 'Update Data';
|
||||||
@@ -62,7 +72,7 @@ class AdvertisementController extends Controller
|
|||||||
// Pastikan model ditemukan
|
// Pastikan model ditemukan
|
||||||
if (!$modelInstance) {
|
if (!$modelInstance) {
|
||||||
info("AdvertisementController@edit: Model tidak ditemukan.");
|
info("AdvertisementController@edit: Model tidak ditemukan.");
|
||||||
return redirect()->route('advertisements.index')->with('error', 'Advertisement not found');
|
return redirect()->route('web.advertisements.index')->with('error', 'Advertisement not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mengambil dan memetakan village_name dan district_name
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
@@ -86,7 +96,7 @@ class AdvertisementController extends Controller
|
|||||||
|
|
||||||
// $route = 'advertisements.update'; // Menggunakan route update untuk form edit
|
// $route = 'advertisements.update'; // Menggunakan route update untuk form edit
|
||||||
// info("AdvertisementController@edit diakses dengan route: $route");
|
// info("AdvertisementController@edit diakses dengan route: $route");
|
||||||
return view('data.advertisements.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions'));
|
return view('data.advertisements.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFields()
|
private function getFields()
|
||||||
|
|||||||
36
app/Http/Controllers/Data/GoogleSheetsController.php
Normal file
36
app/Http/Controllers/Data/GoogleSheetsController.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Data;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTaskGoogleSheet;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GoogleSheetsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menu_id = $request->query('menu_id');
|
||||||
|
$user_menu_permission = $this->permissions[$menu_id];
|
||||||
|
return view('data.google-sheet.index', compact('user_menu_permission'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('data.google-sheet.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
$data = PbgTaskGoogleSheet::find($id);
|
||||||
|
return view('data.google-sheet.show', compact('data'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
return view('data.google-sheet.edit');
|
||||||
|
}
|
||||||
|
}
|
||||||
103
app/Http/Controllers/Data/SpatialPlanningController.php
Normal file
103
app/Http/Controllers/Data/SpatialPlanningController.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?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(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('data.spatialPlannings.index', compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function bulkCreate(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.spatialPlannings.form-upload', compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$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','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(Request $request,string $id)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$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','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
155
app/Http/Controllers/Data/TourismController.php
Normal file
155
app/Http/Controllers/Data/TourismController.php
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Data;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Tourism;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class TourismController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('data.tourisms.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show the form for creating a new rsource.
|
||||||
|
*/
|
||||||
|
public function bulkCreate(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.tourisms.form-upload', compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show th form for creating a new resource
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$title = 'Pariwisata';
|
||||||
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
|
// Mengambil data untuk dropdown
|
||||||
|
$dropdownOptions = [
|
||||||
|
'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')
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = $this->getFields();
|
||||||
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
|
$apiUrl = url('/api/tourisms');
|
||||||
|
|
||||||
|
return view('data.tourisms.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(Request $request, $id)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$title = 'Pariwisata';
|
||||||
|
$subtitle = 'Update Data';
|
||||||
|
|
||||||
|
$modelInstance = Tourism::find($id);
|
||||||
|
// Pastikan model ditemukan
|
||||||
|
if (!$modelInstance) {
|
||||||
|
return redirect()->route('web-tourisms.index') ->with('error', 'Pariwisata tidak ditemukan');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
|
$village = DB::table('villages')->where('village_code', $modelInstance->village_code)->first();
|
||||||
|
$modelInstance->village_name = $village ? $village->village_name : null;
|
||||||
|
|
||||||
|
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
|
||||||
|
$modelInstance->district_name = $district ? $district->district_name : null;
|
||||||
|
|
||||||
|
$dropdownOptions = [
|
||||||
|
'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')
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = $this->getFields();
|
||||||
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
|
$apiUrl = url('/api/tourisms');
|
||||||
|
|
||||||
|
return view('data.tourisms.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFields()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"project_id" => "ID Proyek",
|
||||||
|
"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",
|
||||||
|
"district_name" => "Kecamatan",
|
||||||
|
"village_name" => "Desa",
|
||||||
|
"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",
|
||||||
|
"tki" => "TKI",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFieldTypes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"project_id" => "text",
|
||||||
|
"project_type_id" => "text",
|
||||||
|
"nib" => "text",
|
||||||
|
"business_name" => "text",
|
||||||
|
"oss_publication_date" => "date",
|
||||||
|
"investment_status_description" => "text",
|
||||||
|
"business_form" => "text",
|
||||||
|
"project_risk" => "text",
|
||||||
|
"project_name" => "text",
|
||||||
|
"business_scale" => "text",
|
||||||
|
"business_address" => "text",
|
||||||
|
"district_name" => "combobox",
|
||||||
|
"village_name" => "combobox",
|
||||||
|
"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",
|
||||||
|
"tki" => "text",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
159
app/Http/Controllers/Data/UmkmController.php
Normal file
159
app/Http/Controllers/Data/UmkmController.php
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Data;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Umkm;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class UmkmController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view('data.umkm.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function bulkCreate(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
return view('data.umkm.form-upload', compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$title = 'UMKM';
|
||||||
|
$subtitle = 'Create Data';
|
||||||
|
|
||||||
|
// Mengambil data untuk dropdown
|
||||||
|
$dropdownOptions = [
|
||||||
|
'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'),
|
||||||
|
'business_scale_id' => DB::table('business_scale')->orderBy('business_scale')->pluck('business_scale', 'id'),
|
||||||
|
'permit_status_id' => DB::table('permit_status')->orderBy('permit_status')->pluck('permit_status', 'id'),
|
||||||
|
'business_form_id' => DB::table('business_form')->orderBy('business_form')->pluck('business_form', 'id')
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = $this->getFields();
|
||||||
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
|
$apiUrl = url('/api/umkm');
|
||||||
|
|
||||||
|
return view('data.umkm.form', compact('title', 'subtitle', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(Request $request,$id)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id', 0);
|
||||||
|
$title = 'UMKM';
|
||||||
|
$subtitle = 'Update Data';
|
||||||
|
$modelInstance = Umkm::find($id);
|
||||||
|
// Pastikan model ditemukan
|
||||||
|
if (!$modelInstance) {
|
||||||
|
return redirect()->route('web-umkm.index')->with('error', 'Umkm not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mengambil dan memetakan village_name dan district_name
|
||||||
|
$village = DB::table('villages')->where('village_code', $modelInstance->village_code)->first();
|
||||||
|
$modelInstance->village_name = $village ? $village->village_name : null;
|
||||||
|
|
||||||
|
$district = DB::table('districts')->where('district_code', $modelInstance->district_code)->first();
|
||||||
|
$modelInstance->district_name = $district ? $district->district_name : null;
|
||||||
|
|
||||||
|
$business_scale = DB::table('business_scale')->where('id', $modelInstance->business_scale_id)->first();
|
||||||
|
$modelInstance->business_scale_id = $business_scale ? $business_scale->id : null;
|
||||||
|
|
||||||
|
$permit_status = DB::table('permit_status')->where('id', $modelInstance->permit_status_id)->first();
|
||||||
|
$modelInstance->permit_status_id = $permit_status ? $permit_status->id : null;
|
||||||
|
|
||||||
|
$business_form = DB::table('business_form')->where('id', $modelInstance->business_form_id)->first();
|
||||||
|
$modelInstance->business_form_id = $business_form ? $business_form->id : null;
|
||||||
|
|
||||||
|
// dd($modelInstance['business_form_id']);
|
||||||
|
// Mengambil data untuk dropdown
|
||||||
|
$dropdownOptions = [
|
||||||
|
'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'),
|
||||||
|
'business_scale_id' => DB::table('business_scale')->orderBy('business_scale')->pluck('business_scale', 'id'),
|
||||||
|
'permit_status_id' => DB::table('permit_status')->orderBy('permit_status')->pluck('permit_status', 'id'),
|
||||||
|
'business_form_id' => DB::table('business_form')->orderBy('business_form')->pluck('business_form', 'id')
|
||||||
|
];
|
||||||
|
|
||||||
|
info("AdvertisementController@edit diakses dengan Model Instance: $modelInstance");
|
||||||
|
$fields = $this->getFields();
|
||||||
|
$fieldTypes = $this->getFieldTypes();
|
||||||
|
|
||||||
|
$apiUrl = url('/api/umkm');
|
||||||
|
|
||||||
|
// dd($modelInstance->business_form_id, $dropdownOptions['business_form']);
|
||||||
|
return view('data.umkm.form', compact('title', 'subtitle', 'modelInstance', 'fields', 'fieldTypes', 'apiUrl', 'dropdownOptions','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFields()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"business_name" => "Nama Usaha",
|
||||||
|
"business_address" => "Alamat Usaha",
|
||||||
|
"business_desc" => "Deskripsi Usaha",
|
||||||
|
"business_contact" => "Kontak Usaha",
|
||||||
|
"business_id_number" => "NIB",
|
||||||
|
"business_scale_id" => "Skala Usaha",
|
||||||
|
"owner_id" => "NIK",
|
||||||
|
"owner_name" => "Nama Pemilik",
|
||||||
|
"owner_address" => "Alamat Pemilik",
|
||||||
|
"owner_contact" => "Kontak Pemilik",
|
||||||
|
"business_type" => "Jenis Usaha",
|
||||||
|
"district_name" => "Kecamatan",
|
||||||
|
"village_name" => "Desa",
|
||||||
|
"number_of_employee" => "Jumlah Karyawan",
|
||||||
|
"land_area" => "Luas Tanah",
|
||||||
|
"permit_status_id" => "Ijin Status",
|
||||||
|
"business_form_id" => "Bisnis Form",
|
||||||
|
"revenue" => "Omset"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFieldTypes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"business_name" => "text",
|
||||||
|
"business_address" => "text",
|
||||||
|
"business_desc" => "textarea",
|
||||||
|
"business_contact" => "text",
|
||||||
|
"business_id_number" => "text",
|
||||||
|
"business_scale_id" => "select",
|
||||||
|
"owner_id" => "text",
|
||||||
|
"owner_name" => "text",
|
||||||
|
"owner_address" => "text",
|
||||||
|
"owner_contact" => "text",
|
||||||
|
"business_type" => "text",
|
||||||
|
"district_name" => "combobox",
|
||||||
|
"village_name" => "combobox",
|
||||||
|
"number_of_employee" => "text",
|
||||||
|
"land_area" => "text",
|
||||||
|
"permit_status_id" => "select",
|
||||||
|
"business_form_id" => "select",
|
||||||
|
"revenue" => "text"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
128
app/Http/Controllers/DataSettingController.php
Normal file
128
app/Http/Controllers/DataSettingController.php
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
<?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;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Http\Request as IndexRequest;
|
||||||
|
|
||||||
|
class DataSettingController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(IndexRequest $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
return view("data-settings.index", compact('creator', 'updater', 'destroyer','menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(IndexRequest $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
return view("data-settings.create", compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(IndexRequest $request,string $id)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
$data = DataSetting::findOrFail($id);
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
if(empty($data)){
|
||||||
|
return redirect()->route('data-settings.index')->with('error', 'Invalid id');
|
||||||
|
}
|
||||||
|
return view("data-settings.edit", compact("data", 'menuId'));
|
||||||
|
}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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/Http/Controllers/GoogleApisController.php
Normal file
12
app/Http/Controllers/GoogleApisController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GoogleApisController extends Controller
|
||||||
|
{
|
||||||
|
public function index(){
|
||||||
|
return view('maps.google-api');
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/Http/Controllers/InvitationsController.php
Normal file
12
app/Http/Controllers/InvitationsController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class InvitationsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('invitations.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,17 @@
|
|||||||
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;
|
||||||
use App\Traits\GlobalApiResponse;
|
use App\Traits\GlobalApiResponse;
|
||||||
use Illuminate\Auth\Events\Registered;
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class UsersController extends Controller
|
class UsersController extends Controller
|
||||||
{
|
{
|
||||||
@@ -17,25 +22,35 @@ class UsersController extends Controller
|
|||||||
$users = User::all();
|
$users = User::all();
|
||||||
return $this->resSuccess($users);
|
return $this->resSuccess($users);
|
||||||
}
|
}
|
||||||
public function index(){
|
public function index(Request $request){
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
$users = User::paginate();
|
$users = User::paginate();
|
||||||
return view('master.users.index', compact('users'));
|
return view('master.users.index', compact('users', 'creator', 'updater', 'destroyer','menuId'));
|
||||||
}
|
}
|
||||||
public function create(){
|
public function create(Request $request){
|
||||||
return view('master.users.create');
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$roles = Role::all();
|
||||||
|
return view('master.users.create', compact('roles', 'menuId'));
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
try{
|
||||||
$user = User::create([
|
$user = User::create([
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'email' => $request->email,
|
'email' => $request->email,
|
||||||
@@ -45,32 +60,56 @@ class UsersController extends Controller
|
|||||||
'position' => $request->position
|
'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);
|
||||||
return view('master.users.show', compact('user'));
|
return view('master.users.show', compact('user'));
|
||||||
}
|
}
|
||||||
public function edit($id){
|
public function edit(Request $request, $id){
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
return view('master.users.edit', compact('user'));
|
$roles = Role::all();
|
||||||
|
return view('master.users.edit', compact('user', 'roles', 'menuId'));
|
||||||
}
|
}
|
||||||
public function update(Request $request, $id){
|
public function update(Request $request, $id){
|
||||||
$user = User::find($id);
|
$user = User::find($id);
|
||||||
$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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
146
app/Http/Controllers/MenusController.php
Normal file
146
app/Http/Controllers/MenusController.php
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<?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(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = (int) $request->query('menu_id', 0);
|
||||||
|
$permissions = $this->permissions[$menuId] ?? []; // Avoid undefined index error
|
||||||
|
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('menus.index', compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id'); // Get menu_id from request
|
||||||
|
$menu = Menu::with('children')->find($menuId); // Find the menu
|
||||||
|
|
||||||
|
// Get IDs of all child menus to exclude
|
||||||
|
$excludedIds = $menu ? $this->getChildMenuIds($menu) : [$menuId];
|
||||||
|
|
||||||
|
// Fetch only menus that have children and are not in the excluded list
|
||||||
|
$parent_menus = Menu::whereHas('children')
|
||||||
|
->whereNotIn('id', $excludedIds)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return view("menus.create", compact('parent_menus', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
$menu = Menu::with('children')->find($id);
|
||||||
|
$excludedIds = $menu ? $this->getChildMenuIds($menu) : [$id];
|
||||||
|
|
||||||
|
$parent_menus = Menu::whereHas('children')
|
||||||
|
->whereNotIn('id', $excludedIds)
|
||||||
|
->get();
|
||||||
|
return view("menus.edit", compact('menu','parent_menus', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getChildMenuIds($menu)
|
||||||
|
{
|
||||||
|
$ids = [$menu->id]; // Start with current menu ID
|
||||||
|
|
||||||
|
foreach ($menu->children as $child) {
|
||||||
|
$ids = array_merge($ids, $this->getChildMenuIds($child)); // Recursively fetch children
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
app/Http/Controllers/PaymentRecapsController.php
Normal file
64
app/Http/Controllers/PaymentRecapsController.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PaymentRecapsController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('payment-recaps.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request, string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Http/Controllers/PbgTaskAttachmentsController.php
Normal file
21
app/Http/Controllers/PbgTaskAttachmentsController.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\PbgTaskAttachment;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class PbgTaskAttachmentsController extends Controller
|
||||||
|
{
|
||||||
|
public function show(string $id, Request $request){
|
||||||
|
try{
|
||||||
|
$title = $request->get('type') == "berita-acara" ? "Berita Acara" : "Bukti Bayar";
|
||||||
|
$data = PbgTaskAttachment::findOrFail($id);
|
||||||
|
$pbg = PbgTask::findOrFail($data->pbg_task_id);
|
||||||
|
return view('pbg-task-attachment.show', compact('data', 'pbg', 'title'));
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return view('pages.404');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
app/Http/Controllers/QuickSearchController.php
Normal file
87
app/Http/Controllers/QuickSearchController.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Enums\PbgTaskApplicationTypes;
|
||||||
|
use App\Enums\PbgTaskStatus;
|
||||||
|
use App\Http\Resources\TaskAssignmentsResource;
|
||||||
|
use App\Models\PbgTask;
|
||||||
|
use App\Models\TaskAssignment;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class QuickSearchController extends Controller
|
||||||
|
{
|
||||||
|
public function index(){
|
||||||
|
return view("quick-search.index");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function search_result(Request $request){
|
||||||
|
$keyword = $request->get("keyword");
|
||||||
|
|
||||||
|
return view('quick-search.result', compact('keyword'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quick_search_datatable(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$query = PbgTask::orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$search = $request->get('search');
|
||||||
|
$query->where(function ($q) use ($search) {
|
||||||
|
$q->where('name', 'LIKE', "%$search%")
|
||||||
|
->orWhere('registration_number', 'LIKE', "%$search%")
|
||||||
|
->orWhere('address', 'LIKE', "%$search%")
|
||||||
|
->orWhere('document_number', 'LIKE', "%$search%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json($query->paginate());
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
\Log::error("Error fetching datatable data: " . $e->getMessage());
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Terjadi kesalahan saat mengambil data.',
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$data = PbgTask::with([
|
||||||
|
'pbg_task_retributions',
|
||||||
|
'pbg_task_index_integrations',
|
||||||
|
'pbg_task_retributions.pbg_task_prasarana'
|
||||||
|
])->findOrFail($id);
|
||||||
|
|
||||||
|
$statusOptions = PbgTaskStatus::getStatuses();
|
||||||
|
$applicationTypes = PbgTaskApplicationTypes::labels();
|
||||||
|
|
||||||
|
return view("quick-search.detail", compact("data", 'statusOptions', 'applicationTypes'));
|
||||||
|
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
|
||||||
|
\Log::warning("PbgTask with ID {$id} not found.");
|
||||||
|
return redirect()->route('quick-search.index')->with('error', 'Data tidak ditemukan.');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
\Log::error("Error in QuickSearchController@show: " . $e->getMessage());
|
||||||
|
return response()->view('pages.404', [], 500); // Optional: create `resources/views/errors/500.blade.php`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function task_assignments(Request $request, $uuid){
|
||||||
|
try{
|
||||||
|
$query = TaskAssignment::query()
|
||||||
|
->where('pbg_task_uid', $uuid)
|
||||||
|
->orderBy('id', 'desc');
|
||||||
|
|
||||||
|
if ($request->filled('search')) {
|
||||||
|
$query->where('name', 'like', "%{$request->get('search')}%")
|
||||||
|
->orWhere('email', 'like', "%{$request->get('search')}%");
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskAssignmentsResource::collection($query->paginate(config('app.paginate_per_page', 50)));
|
||||||
|
}catch(\Exception $exception){
|
||||||
|
return response()->json(['message' => $exception->getMessage()], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
app/Http/Controllers/Report/GrowthReportsController.php
Normal file
14
app/Http/Controllers/Report/GrowthReportsController.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Report;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class GrowthReportsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(){
|
||||||
|
return view('report.growth-report.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
20
app/Http/Controllers/Report/ReportTourismController.php
Normal file
20
app/Http/Controllers/Report/ReportTourismController.php
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Report;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\TourismBasedKBLI;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class ReportTourismController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listring of the resource
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$tourismBasedKBLI = TourismBasedKBLI::all();
|
||||||
|
return view('report.tourisms.index', compact('tourismBasedKBLI'));
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/Http/Controllers/ReportPaymentRecapsController.php
Normal file
12
app/Http/Controllers/ReportPaymentRecapsController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ReportPaymentRecapsController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('report-payment-recaps.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/Http/Controllers/ReportPbgPTSPController.php
Normal file
12
app/Http/Controllers/ReportPbgPTSPController.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ReportPbgPTSPController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request){
|
||||||
|
return view('report-pbg-ptsp.index');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,17 +2,37 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\RequestAssignment;
|
namespace App\Http\Controllers\RequestAssignment;
|
||||||
|
|
||||||
|
use App\Enums\PbgTaskApplicationTypes;
|
||||||
|
use App\Enums\PbgTaskFilterData;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\PbgTask;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use App\Enums\PbgTaskStatus;
|
||||||
|
|
||||||
class PbgTaskController extends Controller
|
class PbgTaskController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
return view('request-assignment.index');
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$filter = $request->query('filter');
|
||||||
|
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view('pbg_task.index', [
|
||||||
|
'creator' => $creator,
|
||||||
|
'updater' => $updater,
|
||||||
|
'destroyer' => $destroyer,
|
||||||
|
'filter' => $filter,
|
||||||
|
'filterOptions' => PbgTaskFilterData::getAllOptions(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +40,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
//
|
return view("pbg_task.create");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +48,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +56,10 @@ 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);
|
||||||
|
$statusOptions = PbgTaskStatus::getStatuses();
|
||||||
|
$applicationTypes = PbgTaskApplicationTypes::labels();
|
||||||
|
return view("pbg_task.show", compact("data", 'statusOptions', 'applicationTypes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +67,7 @@ class PbgTaskController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function edit(string $id)
|
public function edit(string $id)
|
||||||
{
|
{
|
||||||
//
|
return view("pbg_task.edit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
295
app/Http/Controllers/RetributionProposalController.php
Normal file
295
app/Http/Controllers/RetributionProposalController.php
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\RetributionProposal;
|
||||||
|
use App\Models\SpatialPlanning;
|
||||||
|
use App\Models\BuildingFunction;
|
||||||
|
use App\Services\RetributionProposalService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
class RetributionProposalController extends Controller
|
||||||
|
{
|
||||||
|
protected RetributionProposalService $proposalService;
|
||||||
|
|
||||||
|
public function __construct(RetributionProposalService $proposalService)
|
||||||
|
{
|
||||||
|
$this->proposalService = $proposalService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of retribution proposals
|
||||||
|
*/
|
||||||
|
public function index(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$query = RetributionProposal::with(['spatialPlanning', 'buildingFunction', 'retributionFormula']);
|
||||||
|
|
||||||
|
// Filtering
|
||||||
|
if ($request->has('building_function_id')) {
|
||||||
|
$query->where('building_function_id', $request->building_function_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('spatial_planning_id')) {
|
||||||
|
$query->where('spatial_planning_id', $request->spatial_planning_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('floor_number')) {
|
||||||
|
$query->where('floor_number', $request->floor_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('has_spatial_planning')) {
|
||||||
|
if ($request->boolean('has_spatial_planning')) {
|
||||||
|
$query->whereNotNull('spatial_planning_id');
|
||||||
|
} else {
|
||||||
|
$query->whereNull('spatial_planning_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search
|
||||||
|
if ($request->has('search')) {
|
||||||
|
$search = $request->search;
|
||||||
|
$query->where(function ($q) use ($search) {
|
||||||
|
$q->where('proposal_number', 'like', "%{$search}%")
|
||||||
|
->orWhere('notes', 'like', "%{$search}%")
|
||||||
|
->orWhereHas('spatialPlanning', function ($sq) use ($search) {
|
||||||
|
$sq->where('name', 'like', "%{$search}%");
|
||||||
|
})
|
||||||
|
->orWhereHas('buildingFunction', function ($bq) use ($search) {
|
||||||
|
$bq->where('name', 'like', "%{$search}%");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sorting
|
||||||
|
$sortBy = $request->get('sort_by', 'created_at');
|
||||||
|
$sortOrder = $request->get('sort_order', 'desc');
|
||||||
|
$query->orderBy($sortBy, $sortOrder);
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
$perPage = $request->get('per_page', 15);
|
||||||
|
$proposals = $query->paginate($perPage);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $proposals,
|
||||||
|
'meta' => [
|
||||||
|
'total_amount' => RetributionProposal::sum('total_retribution_amount'),
|
||||||
|
'total_proposals' => RetributionProposal::count(),
|
||||||
|
'formatted_total_amount' => 'Rp ' . number_format(RetributionProposal::sum('total_retribution_amount'), 0, ',', '.')
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a new retribution proposal
|
||||||
|
*/
|
||||||
|
public function store(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'spatial_planning_id' => 'nullable|exists:spatial_plannings,id',
|
||||||
|
'building_function_id' => 'required|exists:building_functions,id',
|
||||||
|
'floor_number' => 'required|integer|min:1|max:10',
|
||||||
|
'floor_area' => 'required|numeric|min:0.01',
|
||||||
|
'total_building_area' => 'nullable|numeric|min:0.01',
|
||||||
|
'notes' => 'nullable|string|max:1000'
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($request->spatial_planning_id) {
|
||||||
|
$spatialPlanning = SpatialPlanning::findOrFail($request->spatial_planning_id);
|
||||||
|
$proposal = $this->proposalService->createProposalForSpatialPlanning(
|
||||||
|
$spatialPlanning,
|
||||||
|
$request->building_function_id,
|
||||||
|
$request->floor_number,
|
||||||
|
$request->floor_area,
|
||||||
|
$request->total_building_area,
|
||||||
|
$request->notes
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$proposal = $this->proposalService->createStandaloneProposal(
|
||||||
|
$request->building_function_id,
|
||||||
|
$request->floor_number,
|
||||||
|
$request->floor_area,
|
||||||
|
$request->total_building_area,
|
||||||
|
$request->notes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$proposal->load(['spatialPlanning', 'buildingFunction', 'retributionFormula']);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Retribution proposal created successfully',
|
||||||
|
'data' => $proposal
|
||||||
|
], 201);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Failed to create retribution proposal',
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified retribution proposal
|
||||||
|
*/
|
||||||
|
public function show(int $id): JsonResponse
|
||||||
|
{
|
||||||
|
$proposal = RetributionProposal::with(['spatialPlanning', 'buildingFunction', 'retributionFormula'])
|
||||||
|
->findOrFail($id);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $proposal
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified retribution proposal
|
||||||
|
*/
|
||||||
|
public function update(Request $request, int $id): JsonResponse
|
||||||
|
{
|
||||||
|
$proposal = RetributionProposal::findOrFail($id);
|
||||||
|
|
||||||
|
$request->validate([
|
||||||
|
'notes' => 'nullable|string|max:1000'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$proposal->update($request->only(['notes']));
|
||||||
|
|
||||||
|
$proposal->load(['spatialPlanning', 'buildingFunction', 'retributionFormula']);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Retribution proposal updated successfully',
|
||||||
|
'data' => $proposal
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified retribution proposal
|
||||||
|
*/
|
||||||
|
public function destroy(int $id): JsonResponse
|
||||||
|
{
|
||||||
|
$proposal = RetributionProposal::findOrFail($id);
|
||||||
|
$proposal->delete();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Retribution proposal deleted successfully'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get retribution proposal statistics
|
||||||
|
*/
|
||||||
|
public function statistics(): JsonResponse
|
||||||
|
{
|
||||||
|
$stats = $this->proposalService->getStatistics();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $stats
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get total sum of all retribution proposals
|
||||||
|
*/
|
||||||
|
public function totalSum(): JsonResponse
|
||||||
|
{
|
||||||
|
$totalAmount = RetributionProposal::sum('total_retribution_amount');
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => [
|
||||||
|
'total_amount' => $totalAmount,
|
||||||
|
'formatted_total_amount' => 'Rp ' . number_format($totalAmount, 0, ',', '.'),
|
||||||
|
'total_proposals' => RetributionProposal::count()
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get building functions list
|
||||||
|
*/
|
||||||
|
public function buildingFunctions(): JsonResponse
|
||||||
|
{
|
||||||
|
$buildingFunctions = BuildingFunction::whereNotNull('parent_id')
|
||||||
|
->with(['parameter'])
|
||||||
|
->orderBy('name')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'data' => $buildingFunctions
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-detect building function and create proposal
|
||||||
|
*/
|
||||||
|
public function autoCreateProposal(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'spatial_planning_id' => 'nullable|exists:spatial_plannings,id',
|
||||||
|
'building_function_text' => 'required|string',
|
||||||
|
'floor_number' => 'required|integer|min:1|max:10',
|
||||||
|
'floor_area' => 'required|numeric|min:0.01',
|
||||||
|
'total_building_area' => 'nullable|numeric|min:0.01',
|
||||||
|
'notes' => 'nullable|string|max:1000'
|
||||||
|
]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Auto-detect building function
|
||||||
|
$buildingFunction = $this->proposalService->detectBuildingFunction($request->building_function_text);
|
||||||
|
|
||||||
|
if (!$buildingFunction) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Could not detect building function from text',
|
||||||
|
'suggestion' => 'Please specify building function manually'
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->spatial_planning_id) {
|
||||||
|
$spatialPlanning = SpatialPlanning::findOrFail($request->spatial_planning_id);
|
||||||
|
$proposal = $this->proposalService->createProposalForSpatialPlanning(
|
||||||
|
$spatialPlanning,
|
||||||
|
$buildingFunction->id,
|
||||||
|
$request->floor_number,
|
||||||
|
$request->floor_area,
|
||||||
|
$request->total_building_area,
|
||||||
|
$request->notes
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$proposal = $this->proposalService->createStandaloneProposal(
|
||||||
|
$buildingFunction->id,
|
||||||
|
$request->floor_number,
|
||||||
|
$request->floor_area,
|
||||||
|
$request->total_building_area,
|
||||||
|
$request->notes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$proposal->load(['spatialPlanning', 'buildingFunction', 'retributionFormula']);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Retribution proposal created successfully with auto-detected building function',
|
||||||
|
'data' => $proposal,
|
||||||
|
'detected_building_function' => $buildingFunction->name
|
||||||
|
], 201);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Failed to create retribution proposal',
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
164
app/Http/Controllers/RolesController.php
Normal file
164
app/Http/Controllers/RolesController.php
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<?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;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class RolesController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id') ?? $request->input('menu_id');
|
||||||
|
$permissions = $this->permissions[$menuId]?? []; // Avoid undefined index error
|
||||||
|
$creator = $permissions['allow_create'] ?? 0;
|
||||||
|
$updater = $permissions['allow_update'] ?? 0;
|
||||||
|
$destroyer = $permissions['allow_destroy'] ?? 0;
|
||||||
|
|
||||||
|
return view("roles.index", compact('creator', 'updater', 'destroyer', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
return view("roles.create", compact('menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, Request $request)
|
||||||
|
{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
$role = Role::findOrFail($id);
|
||||||
|
return view("roles.edit", compact('role', 'menuId'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, Request $request){
|
||||||
|
try{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
$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', 'menuId'));
|
||||||
|
}catch(\Exception $e){
|
||||||
|
return redirect()->back()->with("error", $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update_menu_permission(Request $request, string $role_id){
|
||||||
|
try{
|
||||||
|
$menuId = $request->query('menu_id');
|
||||||
|
$validateData = $request->validate([
|
||||||
|
"permissions" => "nullable|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);
|
||||||
|
|
||||||
|
// Jika `permissions` tidak ada atau kosong, hapus semua permissions terkait
|
||||||
|
if (!isset($validateData['permissions']) || empty($validateData['permissions'])) {
|
||||||
|
$role->menus()->detach();
|
||||||
|
return redirect()->route("roles.index", ['menu_id' => $menuId])
|
||||||
|
->with('success', 'All menu permissions have been removed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$permissionsArray = [];
|
||||||
|
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("roles.index", ['menu_id' => $menuId])->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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
app/Http/Controllers/RoutingController.php
Executable file → Normal file
26
app/Http/Controllers/RoutingController.php
Executable file → Normal 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,37 +3,70 @@
|
|||||||
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;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
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');
|
$menuId = $request->query('menu_id');
|
||||||
|
$user = Auth::user();
|
||||||
|
$userId = $user->id;
|
||||||
|
|
||||||
|
// Ambil role_id yang dimiliki user
|
||||||
|
$roleIds = DB::table('user_role')
|
||||||
|
->where('user_id', $userId)
|
||||||
|
->pluck('role_id');
|
||||||
|
|
||||||
|
// Ambil data akses berdasarkan role_id dan menu_id
|
||||||
|
$roleAccess = DB::table('role_menu')
|
||||||
|
->whereIn('role_id', $roleIds)
|
||||||
|
->where('menu_id', $menuId)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// Pastikan roleAccess tidak null sebelum mengakses properti
|
||||||
|
$creator = $roleAccess->allow_create ?? 0;
|
||||||
|
$updater = $roleAccess->allow_update ?? 0;
|
||||||
|
$destroyer = $roleAccess->allow_destroy ?? 0;
|
||||||
|
|
||||||
|
return view('settings.syncronize.index', compact('creator', 'updater', 'destroyer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncPbgTask(){
|
public function syncPbgTask(){
|
||||||
$res = (new ServiceSIMBG())->syncTaskList();
|
$res = $this->service_simbg->syncTaskPBG();
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncronizeTask(Request $request){
|
public function syncronizeTask(Request $request){
|
||||||
$res = (new ServiceSIMBG())->syncTaskList();
|
$res = $this->service_simbg->syncTaskPBG();
|
||||||
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);
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function syncTaskAssignments($uuid){
|
||||||
|
$res = $this->service_simbg->syncTaskAssignments($uuid);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/Http/Controllers/TpatptsController.php
Normal file
28
app/Http/Controllers/TpatptsController.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TpatptsController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('tpa-tpt.index');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(string $id)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/Http/Requests/Auth/LoginRequest.php
Executable file → Normal file
0
app/Http/Requests/Auth/LoginRequest.php
Executable file → Normal file
39
app/Http/Requests/BusinessIndustryRequest.php
Normal file
39
app/Http/Requests/BusinessIndustryRequest.php
Normal 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'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
33
app/Http/Requests/CustomersRequest.php
Normal file
33
app/Http/Requests/CustomersRequest.php
Normal 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'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/Http/Requests/DataSettingRequest.php
Normal file
31
app/Http/Requests/DataSettingRequest.php
Normal 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",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/Http/Requests/ExcelUploadRequest.php
Normal file
28
app/Http/Requests/ExcelUploadRequest.php
Normal 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"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
35
app/Http/Requests/MenuRequest.php
Normal file
35
app/Http/Requests/MenuRequest.php
Normal 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'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
62
app/Http/Requests/PbgTaskMultiStepRequest.php
Normal file
62
app/Http/Requests/PbgTaskMultiStepRequest.php
Normal 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.",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/Http/Requests/RoleRequest.php
Normal file
30
app/Http/Requests/RoleRequest.php
Normal 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',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
52
app/Http/Requests/SpatialPlanningRequest.php
Normal file
52
app/Http/Requests/SpatialPlanningRequest.php
Normal 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.',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user