From be96576f3d0a42e62c5445e57076c83d60049928 Mon Sep 17 00:00:00 2001 From: ISMAIL MASSERAN Date: Sun, 9 Aug 2026 10:18:26 +0800 Subject: [PATCH] DONE: use flexible name for api call in frontend --- .env.docker | 54 +++++++++++++ .gitignore | 2 +- README.md | 50 +++++++++++++ REMARK.md | 5 ++ .../Auth/ImpersonateController.php | 52 +++++++++++++ app/Http/Controllers/Auth/LoginController.php | 46 ++++++++++-- app/Http/Controllers/KhazanahController.php | 3 + app/Http/Controllers/OperasiController.php | 3 + app/Providers/AuthServiceProvider.php | 4 +- app/User.php | 12 +++ app/helpers.php | 15 ++++ composer.json | 4 + composer.lock | 75 ++++++++++++++++++- docker/php/Dockerfile | 40 +++++----- .../views/admin/customer_index.blade.php | 2 +- resources/views/admin/customer_info.blade.php | 2 +- resources/views/admin/poskod.blade.php | 2 +- resources/views/aliran_tunai/index.blade.php | 9 +-- .../views/callcenter/callnotisjbg2.blade.php | 2 +- resources/views/callcenter/index.blade.php | 2 +- .../views/callcenter/indexnama.blade.php | 2 +- resources/views/callcenter/v1/info.blade.php | 2 +- resources/views/callcenter/v2/index.blade.php | 2 +- resources/views/callcenter/v2/info.blade.php | 2 +- resources/views/customers/v1/index.blade.php | 2 +- resources/views/customers/v1/info.blade.php | 2 +- resources/views/customers/v2/index.blade.php | 9 +-- resources/views/customers/v2/info.blade.php | 32 +++++--- resources/views/errors/alert.blade.php | 2 +- resources/views/gadaian/v1/edit.blade.php | 2 +- resources/views/gadaian/v1/index.blade.php | 2 +- resources/views/gadaian/v2/edit.blade.php | 6 +- resources/views/gadaian/v2/index.blade.php | 4 +- .../views/homepage/khazanah/home.blade.php | 2 +- .../views/homepage/penilai/home.blade.php | 2 +- .../views/homepage/teller/home.blade.php | 3 +- .../views/khazanah/agingbulanan.blade.php | 2 +- resources/views/khazanah/bajet.blade.php | 2 +- resources/views/khazanah/gadaian.blade.php | 2 +- resources/views/khazanah/index.blade.php | 2 +- resources/views/khazanah/info.blade.php | 2 +- resources/views/khazanah/kelulusan.blade.php | 4 +- .../views/khazanah/khazanahserahan.blade.php | 2 +- .../khazanah/laporan/agingbulanan.blade.php | 2 +- .../khazanah/laporan/alirantunai.blade.php | 2 +- .../views/khazanah/laporan/ansuran.blade.php | 2 +- .../laporan/batalsuratgadai.blade.php | 2 +- .../khazanah/laporan/datalejer_am.blade.php | 2 +- .../khazanah/laporan/denominasi.blade.php | 2 +- .../views/khazanah/laporan/gadaian.blade.php | 2 +- .../khazanah/laporan/imbangduga.blade.php | 2 +- .../laporan/imbangduga_akru.blade.php | 2 +- .../khazanah/laporan/kawalanstok.blade.php | 2 +- .../khazanah/laporan/marhunharian.blade.php | 2 +- .../laporan/marhunterkumpul.blade.php | 2 +- .../khazanah/laporan/pelangganbaru.blade.php | 2 +- .../khazanah/laporan/penebusan.blade.php | 2 +- .../khazanah/laporan/perbelanjaan.blade.php | 2 +- .../views/khazanah/laporan/petibesi.blade.php | 2 +- .../laporan/ringkasanharian.blade.php | 2 +- .../laporan/ringkasanterkumpul.blade.php | 2 +- .../khazanah/laporan/serahgadai.blade.php | 2 +- .../khazanah/laporan/serahmarhun.blade.php | 2 +- .../laporan/stokauditbersih.blade.php | 2 +- .../laporan/stokauditdetails.blade.php | 2 +- .../khazanah/laporan/tuntutbaki.blade.php | 2 +- .../views/khazanah/laporan/upah.blade.php | 2 +- .../views/khazanah/laporan/wakil.blade.php | 2 +- .../laporanujrah/ansuranujrah.blade.php | 2 +- .../laporanujrah/gadaianujrah.blade.php | 2 +- .../ringkasanharianujrah.blade.php | 2 +- resources/views/khazanah/panjar.blade.php | 4 +- .../views/khazanah/pendahuluan.blade.php | 2 +- .../views/khazanah/pendahuluanserah.blade.php | 2 +- .../khazanah/pendahuluanserahanmain.blade.php | 2 +- .../views/khazanah/permohonanwang.blade.php | 2 +- .../views/khazanah/rekodpermohonan.blade.php | 2 +- resources/views/khazanah/saginfo.blade.php | 2 +- resources/views/khazanah/serahan.blade.php | 2 +- resources/views/khazanah/tebus.blade.php | 2 +- resources/views/khazanah/v1/info.blade.php | 2 +- resources/views/khazanah/v2/info.blade.php | 2 +- resources/views/khazanah/wakil.blade.php | 2 +- resources/views/layouts/app.blade.php | 6 +- .../views/layouts/app_callcenter.blade.php | 3 + resources/views/layouts/app_operasi.blade.php | 3 + .../partials/impersonation_nav.blade.php | 11 +++ .../views/lelongan/index-khazanah.blade.php | 6 +- resources/views/lelongan/index.blade.php | 4 +- .../views/onetimepassword/home.blade.php | 2 +- .../views/operasi/daftar_kakitangan.blade.php | 46 ++++++++++++ .../views/operasi/edit_marginmutu.blade.php | 2 +- resources/views/operasi/hargaemas.blade.php | 2 +- resources/views/operasi/kelulusan.blade.php | 4 +- .../views/operasi/komuditi/index.blade.php | 2 +- .../komuditi/rekod_transaksi.blade.php | 2 +- .../penebusan/v1/index-khazanah.blade.php | 2 +- resources/views/penebusan/v1/index.blade.php | 2 +- .../penebusan/v2/index-khazanah.blade.php | 2 +- .../views/penebusan/v2/index.blade-backup.php | 2 +- resources/views/penebusan/v2/index.blade.php | 4 +- routes/web.php | 6 ++ 102 files changed, 523 insertions(+), 146 deletions(-) create mode 100644 .env.docker create mode 100644 REMARK.md create mode 100644 app/Http/Controllers/Auth/ImpersonateController.php create mode 100644 app/helpers.php create mode 100644 resources/views/layouts/partials/impersonation_nav.blade.php diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000..79c1ea3 --- /dev/null +++ b/.env.docker @@ -0,0 +1,54 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY=base64:O1XZDqK4H6+3GdrODgCaLr2l+OoWvgVhYr0GJ1KizW8= +APP_DEBUG=true +APP_URL=http://localhost +# API_URL=http://api-annurv2.test +API_URL=http://host.docker.internal:8080 +API_URL_KOOP=http://host.docker.internal:8080 +API_URL_PKB=http://host.docker.internal:8080 +API_ARRAHNBID=http://lelong.test/api/ + +LOG_CHANNEL=stack +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=mysql +DB_PORT=3306 +DB_DATABASE=kaunter_erahn +DB_USERNAME=kaunteruser +DB_PASSWORD=password + +BROADCAST_DRIVER=pusher +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +PUSHER_APP_ID=1132718 +PUSHER_APP_KEY=26b0ec2f297f94b7aa9b +PUSHER_APP_SECRET=421b61fb5a8ecce477a6 + +MAIL_MAILER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +MYKAD_READER_PORT=8085 +MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1ed293c..80ba177 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ Homestead.yaml npm-debug.log yarn-error.log /.vscode -docker-compose.yml docker_src/ +**/.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index f821d23..ca86015 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ If you does't know what is this you probably in wrong project + +```sql +--- for all ip +CREATE USER 'kaunteruser'@'%' IDENTIFIED BY 'your_password'; + +--- for specific ip +CREATE USER 'kaunteruser'@'localhost' IDENTIFIED BY 'your_password'; + +GRANT ALL PRIVILEGES ON kaunter_erahn.* TO 'kaunteruser'@'%'; +FLUSH PRIVILEGES; +``` + +# ADDITIONAL NOTE + +## customers/v2/index.blade.php is modal to register customer + +## Min Komoditi = RM5000 + +# System Flowchart + +## Proses Gadaian +1) Pelanggan datang bawa marhun +2) Teller daftar maklumat pelanggan jika pelanggan baharu +3) Serah marhun ke penilai untuk timbang +4) Teller daftar marhun di sistem berdasarkan maklumat dari penilai +5) Penilai print SAG dan serah marhun ke Khazanah (PC/PPC) - __khazanah can still scan still scan though__ +6) Khazanah scan barcode dekat SAG untuk masuk ke dalam peti besi +* table involved - gadai.semakbarcode (default is blank, after is Lulus) +7) DONE + +## Setup new branch command: +1. Duplicate previous branch table - use erahn_{{name}} +```sql +SET FOREIGN_KEY_CHECKS = 0; + +SET SESSION group_concat_max_len = 1000000; + +SELECT GROUP_CONCAT( + CONCAT('TRUNCATE TABLE `', table_name, '`') + SEPARATOR '; ' +) INTO @sql +FROM information_schema.tables +WHERE table_schema = DATABASE(); + +SELECT @sql; --- copy the output and paste it + +SET FOREIGN_KEY_CHECKS = 1; +``` +2. Add new cawangan kod on master_erahn.arrahn_master_db and and kaunter_erahn.cawangan +3. Register new cawangan detail in erahn_{{name}}.cawangan \ No newline at end of file diff --git a/REMARK.md b/REMARK.md new file mode 100644 index 0000000..313b68a --- /dev/null +++ b/REMARK.md @@ -0,0 +1,5 @@ +## CAWANGAN XTRA - X0301 +- WAN NUR FATIN NATASYA BINTI W M AZHARI - PENILAI +- MOHAMAD KHAIRULNIZAN BIN JUSOF - TELLER +- MOHAMAD AZUHAIDIE BIN AHMAD - PPC +- WAN NURUL AMIRA BINTI WAN HARON - PC diff --git a/app/Http/Controllers/Auth/ImpersonateController.php b/app/Http/Controllers/Auth/ImpersonateController.php new file mode 100644 index 0000000..dab764a --- /dev/null +++ b/app/Http/Controllers/Auth/ImpersonateController.php @@ -0,0 +1,52 @@ +middleware('auth'); + } + + public function impersonate(Request $request, $id): RedirectResponse + { + Gate::authorize('impersonate'); + + $impersonator = $request->user(); + $id = (int) $id; + $target = User::findOrFail($id); + + if ($target->id === $request->user()->id) { + return back()->with('error', 'Tidak boleh impersonate diri sendiri.'); + } + + if (method_exists($target, 'canBeImpersonated') && !$target->canBeImpersonated()) { + return back()->with('error', 'Akaun ini tidak boleh di-impersonate.'); + } + + $request->user()->impersonate($target); + + return redirect()->route('home'); + } + + public function leave(Request $request): RedirectResponse + { + if ($request->user() && method_exists($request->user(), 'isImpersonated') && $request->user()->isImpersonated()) { + $impersonated = $request->user(); + $impersonator = method_exists($impersonated, 'impersonator') ? $impersonated->impersonator() : null; + + $request->user()->leaveImpersonation(); + } + + return redirect()->route('home'); + } +} + diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index f29fcc2..b9abb66 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -60,9 +60,7 @@ class LoginController extends Controller 'password' => 'required|string', ]); - $credentials = $request->only('email', 'password'); - - if (Auth::guard('web')->attempt($credentials)) { + if ($this->attemptWebLogin($request)) { $auth_user = Auth::guard('web')->user(); $api_url = config('api.url'); @@ -103,9 +101,7 @@ class LoginController extends Controller 'password' => 'required|string', ]); - $credentials = $request->only('email', 'password'); - - if (Auth::guard('dashboard')->attempt($credentials,true)) { + if ($this->attemptDashboardLogin($request)) { $auth_user = Auth::guard('dashboard')->user(); $user_login['nama'] = $auth_user['name']; @@ -187,4 +183,42 @@ class LoginController extends Controller return response()->json($kakitangan,200); } + + /** + * In local environment, log in by email only (password ignored). + */ + private function attemptWebLogin(Request $request): bool + { + if (app()->environment('local')) { + $user = User::where('email', $request->email)->first(); + if ($user) { + Auth::guard('web')->login($user); + + return true; + } + + return false; + } + + return Auth::guard('web')->attempt($request->only('email', 'password')); + } + + /** + * In local environment, log in by email only (password ignored). + */ + private function attemptDashboardLogin(Request $request): bool + { + if (app()->environment('local')) { + $user = Dashboard::where('email', $request->email)->first(); + if ($user) { + Auth::guard('dashboard')->login($user, true); + + return true; + } + + return false; + } + + return Auth::guard('dashboard')->attempt($request->only('email', 'password'), true); + } } diff --git a/app/Http/Controllers/KhazanahController.php b/app/Http/Controllers/KhazanahController.php index 03e7252..a4b074b 100644 --- a/app/Http/Controllers/KhazanahController.php +++ b/app/Http/Controllers/KhazanahController.php @@ -505,6 +505,9 @@ class KhazanahController extends Controller public function mintakatalaluansemula(Request $request) { + if (app()->environment('local')) { + return "True"; + } if(Hash::check($request->passsemula, Auth::user()->password)) { diff --git a/app/Http/Controllers/OperasiController.php b/app/Http/Controllers/OperasiController.php index 7418912..9c68534 100644 --- a/app/Http/Controllers/OperasiController.php +++ b/app/Http/Controllers/OperasiController.php @@ -321,6 +321,9 @@ class OperasiController extends Controller public function mintakatalaluansemula(Request $request) { + if (app()->environment('local')) { + return "True"; + } if (Hash::check($request->passsemula, Auth::user()->password)) { return "True"; diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 3049068..08a3ae1 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -25,6 +25,8 @@ class AuthServiceProvider extends ServiceProvider { $this->registerPolicies(); - // + Gate::define('impersonate', function ($user) { + return $user->canImpersonate(); + }); } } diff --git a/app/User.php b/app/User.php index 33e4953..70034b8 100644 --- a/app/User.php +++ b/app/User.php @@ -6,9 +6,11 @@ use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Lab404\Impersonate\Models\Impersonate; class User extends Authenticatable { + use Impersonate; use Notifiable; protected $guard = 'web'; @@ -43,4 +45,14 @@ class User extends Authenticatable { return $this->hasOne(Cawangan::class, 'kodcaw', 'cawangan'); } + + public function canImpersonate(): bool + { + return in_array($this->roles ?? '', ['admin'], true); + } + + public function canBeImpersonated(): bool + { + return ($this->roles ?? '') !== 'admin'; + } } diff --git a/app/helpers.php b/app/helpers.php new file mode 100644 index 0000000..974dacb --- /dev/null +++ b/app/helpers.php @@ -0,0 +1,15 @@ + @endsection \ No newline at end of file diff --git a/resources/views/aliran_tunai/index.blade.php b/resources/views/aliran_tunai/index.blade.php index 9459d54..384fad4 100644 --- a/resources/views/aliran_tunai/index.blade.php +++ b/resources/views/aliran_tunai/index.blade.php @@ -26,7 +26,7 @@
@php $auth_user = Auth::user();@endphp - +
@@ -348,7 +348,7 @@
@endsection diff --git a/resources/views/khazanah/saginfo.blade.php b/resources/views/khazanah/saginfo.blade.php index 402bfd0..40638d2 100644 --- a/resources/views/khazanah/saginfo.blade.php +++ b/resources/views/khazanah/saginfo.blade.php @@ -104,7 +104,7 @@ @@ -199,7 +199,7 @@
diff --git a/resources/views/layouts/app_callcenter.blade.php b/resources/views/layouts/app_callcenter.blade.php index bed2238..60a9477 100644 --- a/resources/views/layouts/app_callcenter.blade.php +++ b/resources/views/layouts/app_callcenter.blade.php @@ -105,6 +105,7 @@
diff --git a/resources/views/layouts/partials/impersonation_nav.blade.php b/resources/views/layouts/partials/impersonation_nav.blade.php new file mode 100644 index 0000000..b859cab --- /dev/null +++ b/resources/views/layouts/partials/impersonation_nav.blade.php @@ -0,0 +1,11 @@ +@if(Auth::check() && method_exists(Auth::user(), 'isImpersonated') && Auth::user()->isImpersonated()) + +@endif + diff --git a/resources/views/lelongan/index-khazanah.blade.php b/resources/views/lelongan/index-khazanah.blade.php index 71c4f23..062a93e 100644 --- a/resources/views/lelongan/index-khazanah.blade.php +++ b/resources/views/lelongan/index-khazanah.blade.php @@ -200,7 +200,7 @@ } }); - var api = ''; + var api = "{{ api_url_for_browser() }}"; let nw = 0; function wakilfunction(e) @@ -536,7 +536,7 @@ function ubahwakil(e) { let norujukan = $('#norujukan').val(); - let api = "{{ config('api.url') }}"; + let api = "{{ api_url_for_browser() }}"; let nowakil = nw; let jenis = ''; @@ -627,7 +627,7 @@ function ubahwakil(e) let norujukan = $('#norujukan').val(); - let api = "{{ config('api.url') }}"; + let api = "{{ api_url_for_browser() }}"; let nowakil = 0; let jenis = ''; let mohon = ''; diff --git a/resources/views/lelongan/index.blade.php b/resources/views/lelongan/index.blade.php index 2eab543..a53b02a 100644 --- a/resources/views/lelongan/index.blade.php +++ b/resources/views/lelongan/index.blade.php @@ -229,7 +229,7 @@ } }); - var api = ''; + var api = "{{ api_url_for_browser() }}"; let nw = 0; function wakilfunction(e) @@ -565,7 +565,7 @@ function ubahwakil(e) { let norujukan = $('#norujukan').val(); - let api = "{{ config('api.url') }}"; + let api = "{{ api_url_for_browser() }}"; let nowakil = nw; let jenis = ''; diff --git a/resources/views/onetimepassword/home.blade.php b/resources/views/onetimepassword/home.blade.php index 0c010b0..689f8f8 100644 --- a/resources/views/onetimepassword/home.blade.php +++ b/resources/views/onetimepassword/home.blade.php @@ -102,7 +102,7 @@ $(document).ready(function() function carila() { - var api_url = ""; + var api_url = "{{ api_url_for_browser() }}"; var noic = $('#noic').val(); diff --git a/resources/views/operasi/daftar_kakitangan.blade.php b/resources/views/operasi/daftar_kakitangan.blade.php index bfc3bc0..fd61936 100644 --- a/resources/views/operasi/daftar_kakitangan.blade.php +++ b/resources/views/operasi/daftar_kakitangan.blade.php @@ -138,6 +138,19 @@ edit work settings + @if( + app()->environment('local') + && + in_array($auth_user->roles, ['admin']) + && $staff->roles != 'admin' + && $staff->id != $auth_user->id + && !(Auth::check() && method_exists(Auth::user(), 'isImpersonated') && Auth::user()->isImpersonated()) + ) +
+ @csrf + +
+ @endif @elseif($auth_user->roles == 'admin') {{--
@@ -147,6 +160,18 @@ work settings restore + @if( + app()->environment('local') + && + $staff->roles != 'admin' + && $staff->id != $auth_user->id + && !(Auth::check() && method_exists(Auth::user(), 'isImpersonated') && Auth::user()->isImpersonated()) + ) + + @csrf + +
+ @endif {{-- --}} @endif @@ -223,6 +248,27 @@ }).catch(swal.noop) }); + $("#rekod_kakitangan").on('click', ".btn-impersonate", function(){ + var form = $(this).closest('form'); + var staffName = $(this).data('staff-name'); + + Swal.fire({ + title: 'Menyamar sebagai Kakitangan?', + text: "Anda akan log masuk sebagai " + staffName + ".", + type: 'warning', + showCancelButton: true, + confirmButtonClass: 'btn btn-secondary', + cancelButtonClass: 'btn btn-warning', + confirmButtonText: 'Ya, menyamar', + cancelButtonText: 'Batal!', + buttonsStyling: false + }).then(function(result) { + if (result.isConfirmed) { + form.submit(); + } + }).catch(swal.noop) + }); + function verifyregister(){ var cawangan = $('#cawangan').val(); var role = $('#role').val(); diff --git a/resources/views/operasi/edit_marginmutu.blade.php b/resources/views/operasi/edit_marginmutu.blade.php index ae1333e..ee34287 100644 --- a/resources/views/operasi/edit_marginmutu.blade.php +++ b/resources/views/operasi/edit_marginmutu.blade.php @@ -85,7 +85,7 @@ $(document).ready(function() { }; $.ajax({ - url: '{{ config("api.url") }}/api/maxmutuemas/update', + url: '{{ api_url_for_browser() }}/api/maxmutuemas/update', type: 'POST', data: formData, success: function(response) { diff --git a/resources/views/operasi/hargaemas.blade.php b/resources/views/operasi/hargaemas.blade.php index 1bce3c1..a689626 100644 --- a/resources/views/operasi/hargaemas.blade.php +++ b/resources/views/operasi/hargaemas.blade.php @@ -95,7 +95,7 @@