From f1a950fb5140d516cffea8b3806733fb259ede52 Mon Sep 17 00:00:00 2001 From: Ain Izazi Date: Tue, 23 Sep 2025 10:23:34 +0800 Subject: [PATCH 01/24] add no tel di sag --- resources/views/print/sag_ujrah_3.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/print/sag_ujrah_3.blade.php b/resources/views/print/sag_ujrah_3.blade.php index d3d1f36..8c13d4e 100644 --- a/resources/views/print/sag_ujrah_3.blade.php +++ b/resources/views/print/sag_ujrah_3.blade.php @@ -1309,7 +1309,7 @@

{{ $cawangan_detail['namacaw'] }}

{{ $cawangan_detail['alamat1'] }}

{{ $cawangan_detail['alamat2'] }}

-

{{ $cawangan_detail['notel'] }}

+

No Tel: {{ $cawangan_detail['notel'] }}

From cab39e66041049e545d5675fb90a69c250b0b00b Mon Sep 17 00:00:00 2001 From: Afiq Hamzah Date: Sun, 5 Oct 2025 16:34:16 +0800 Subject: [PATCH 02/24] Merge with feature/aiman/pampasan/sempornaV2 --- CLAUDE.md | 192 +++ app/Helper.php | 71 +- app/Http/Controllers/KhazanahController.php | 272 +++- app/Http/Controllers/OperasiController.php | 53 +- app/Http/Controllers/PenebusanController.php | 27 +- app/Http/Kernel.php | 1 + app/Http/Middleware/RoleAccess.php | 71 + resources/js/app.js | 30 + resources/js/bootstrap.js | 6 +- .../views/khazanah/pampasan_detail.blade.php | 282 ++++ resources/views/khazanah/panjar.blade.php | 1165 +++++++++++------ resources/views/layouts/app.blade.php | 2 +- resources/views/modal/denopampasan.blade.php | 199 +++ resources/views/modal/panjar.blade.php | 26 +- resources/views/operasi/kelulusan.blade.php | 873 ++++++------ resources/views/penebusan/v2/index.blade.php | 180 ++- .../views/print/laporan_tebus_ujrah.blade.php | 9 +- .../views/print/resit/resitpampasan.blade.php | 258 ++++ .../views/print/surat_pampasan.blade.php | 278 ++++ routes/web.php | 21 +- 20 files changed, 3224 insertions(+), 792 deletions(-) create mode 100644 CLAUDE.md create mode 100644 app/Http/Middleware/RoleAccess.php create mode 100644 resources/js/app.js create mode 100644 resources/views/khazanah/pampasan_detail.blade.php create mode 100644 resources/views/modal/denopampasan.blade.php create mode 100644 resources/views/print/resit/resitpampasan.blade.php create mode 100644 resources/views/print/surat_pampasan.blade.php diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b37c176 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,192 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is the **Kaunter** application, part of the Arrahn PKB (Pajak Gadai Sistem) - an Islamic pawn shop/mortgage management system. This Laravel 7.x application serves as the counter/teller interface for managing pawn transactions, customer interactions, and branch operations within a larger microservices architecture. + +## Application Architecture + +### Core Business Domain +The application manages Islamic financial transactions including: +- **Gadaian** - Pawn/mortgage transactions with Islamic finance compliance +- **Penebusan** - Redemption and repayment processes +- **Customer Management** - Customer records with document management +- **Marhun** - Collateral item management (primarily gold jewelry) +- **Treasury Operations** - Cash flow and financial reconciliation + +### Role-Based Access Control +The system implements 8 distinct user roles with dedicated middleware: +- `teller` - Front desk operations +- `khazanah` - Treasury/financial management +- `operasi` - Operations management +- `admin` - Administrative functions +- `penilai` - Item appraisers +- `callcenter` - Customer service +- `audit` - Financial auditing +- `akaun` - Accounting functions + +Each role has specific controllers, views, and middleware (`app/Http/Middleware/`). + +### API-First Architecture +Controllers primarily delegate to external APIs rather than direct database operations: +- API URLs configured via `config('api.url')` +- API verification settings via `config('app.api_verify')` +- Multi-zone API support for different business units + +## Development Commands + +### Laravel Application Commands +```bash +# Install dependencies (use Docker containers as per parent repository) +docker compose run --rm composer install +docker compose run --rm npm install + +# Generate application key +docker compose run --rm artisan key:generate + +# Run migrations +docker compose run --rm artisan migrate +docker compose run --rm artisan migrate:fresh + +# Clear caches +docker compose run --rm artisan cache:clear +docker compose run --rm artisan config:clear +docker compose run --rm artisan view:clear +``` + +### Frontend Asset Management +```bash +# Development build with watch +docker compose run --rm npm run dev +docker compose run --rm npm run watch + +# Production build +docker compose run --rm npm run production + +# Hot reload for development +docker compose run --rm npm run hot +``` + +### Testing +```bash +# Run all tests +docker compose run --rm vendor/bin/phpunit + +# Run specific test suites +docker compose run --rm vendor/bin/phpunit --testsuite=Unit +docker compose run --rm vendor/bin/phpunit --testsuite=Feature + +# Run with coverage +docker compose run --rm vendor/bin/phpunit --coverage-html coverage +``` + +### Custom Artisan Commands (Financial Operations) +```bash +# Daily financial operations +docker compose run --rm artisan akru:daily +docker compose run --rm artisan imbangduga:daily + +# Monthly operations +docker compose run --rm artisan backup:stokaudit + +# System maintenance +docker compose run --rm artisan reset:role-daily +docker compose run --rm artisan check:lelong-tawarruq +``` + +## Key Application Components + +### Core Models & Relationships +- **`Gadaian`** - Central pawn transaction model with customer and marhun relationships +- **`Customer`** - Uses Spatie MediaLibrary for document management +- **`Penebusan`** - Redemption transactions linked to gadaian records +- **`Marhun`** - Collateral items with detailed specifications +- **`HargaEmas`** - Gold pricing with historical tracking +- **`ImbangDuga`** - Trial balance for financial reconciliation + +### Business Services +- **`CustomerService`** - Customer operations including automated number generation +- **`ImbangdugaServices`** - Financial reconciliation and trial balance operations + +### Event System +Real-time dashboard updates via Laravel Events: +- Dashboard notifications: `GadaiNotify`, `TebusNotify`, `KeuntunganNotify` +- Process events: `AutoSerahan`, `SerahanPenilai` +- User notifications: `NotifikasiPembayaran`, `NotifikasiKelulusan` + +### Configuration Files +- **`config/redeemoption.php`** - Business logic toggles for redemption features +- **`config/adminlte.php`** - AdminLTE dashboard configuration +- **Environment files** - Multiple environment configurations in `env.docker.example/` + +## Technology Stack + +### Laravel Packages +- **AdminLTE 3** (`jeroennoten/laravel-adminlte`) - Administrative interface +- **Spatie MediaLibrary** - File and document management +- **DomPDF** (`barryvdh/laravel-dompdf`) - PDF report generation +- **Pusher** - Real-time notifications +- **Twilio SDK** - SMS communication +- **DataTables** (`yajra/laravel-datatables-oracle`) - Advanced table management +- **QR Code & Barcode** - Document generation utilities + +### Frontend Stack +- **Laravel Mix** - Asset compilation (Webpack wrapper) +- **AdminLTE 3** - Bootstrap-based admin template +- **jQuery** - DOM manipulation and AJAX +- **Socket.io** - Real-time communication client +- **Bootstrap 4** - CSS framework + +## Development Workflow + +### Environment Setup +1. Copy appropriate environment file from `env.docker.example/` directory +2. Configure database connections for multi-zone setup +3. Set API endpoints for microservices communication +4. Configure Pusher for real-time features +5. Set up Twilio credentials for SMS functionality + +### Working with Roles +When developing role-specific features: +1. Check relevant middleware in `app/Http/Middleware/` +2. Use role-specific views in `resources/views/homepage/{role}/` +3. Follow role-based routing patterns in `routes/web.php` +4. Ensure API calls respect role permissions + +### API Integration Pattern +When adding new functionality: +1. Controllers should primarily make API calls rather than direct DB operations +2. Use Laravel HTTP client for external API communication +3. Handle API responses consistently across controllers +4. Implement proper error handling for API failures + +### Testing Islamic Finance Logic +- Use `php artisan check:lelong-tawarruq` to verify Islamic compliance +- Test accrual calculations with `php artisan akru:daily` +- Validate trial balance with `php artisan imbangduga:daily` + +## File Structure Notes + +### View Organization +- **Versioned views** - `v1/` and `v2/` directories indicate system evolution +- **Role-based dashboards** - Separate homepage views for each user role +- **Business-specific templates** - Islamic finance compliance features + +### Custom Commands Location +All financial operation commands are in `app/Console/Commands/` with descriptive names indicating their business purpose. + +### Configuration Patterns +- Business logic configuration separated into dedicated config files +- Environment-specific settings in docker example files +- Multi-zone database configuration support + +## Important Development Notes + +- This application is part of a Docker microservices architecture +- Changes should maintain Islamic finance compliance requirements +- Real-time features depend on Pusher configuration +- Role-based access control is fundamental to all operations +- API integrations are critical - local database operations are minimal +- Multi-language support focuses on Malaysian Malay context \ No newline at end of file diff --git a/app/Helper.php b/app/Helper.php index a43ca4f..386b6b5 100644 --- a/app/Helper.php +++ b/app/Helper.php @@ -1,20 +1,83 @@ format("d-m-Y"); } + + public static function terbilangBm(int $number): string + { + $units = [ + 0 => 'kosong', + 1 => 'satu', + 2 => 'dua', + 3 => 'tiga', + 4 => 'empat', + 5 => 'lima', + 6 => 'enam', + 7 => 'tujuh', + 8 => 'lapan', + 9 => 'sembilan', + 10 => 'sepuluh', + 11 => 'sebelas' + ]; + + if ($number < 0) return 'negatif ' . self::terbilangBm(abs($number)); + if ($number < 12) return $units[$number]; + if ($number < 20) return self::terbilangBm($number - 10) . ' belas'; + if ($number < 100) { + $tens = intdiv($number, 10); + $rest = $number % 10; + return self::terbilangBm($tens) . ' puluh' . ($rest ? ' ' . self::terbilangBm($rest) : ''); + } + if ($number < 200) return 'seratus' . ($number > 100 ? ' ' . self::terbilangBm($number - 100) : ''); + if ($number < 1000) { + $hundreds = intdiv($number, 100); + $rest = $number % 100; + return self::terbilangBm($hundreds) . ' ratus' . ($rest ? ' ' . self::terbilangBm($rest) : ''); + } + if ($number < 2000) return 'seribu' . ($number > 1000 ? ' ' . self::terbilangBm($number - 1000) : ''); + if ($number < 1000000) { + $thousands = intdiv($number, 1000); + $rest = $number % 1000; + return self::terbilangBm($thousands) . ' ribu' . ($rest ? ' ' . self::terbilangBm($rest) : ''); + } + if ($number < 1000000000) { + $millions = intdiv($number, 1000000); + $rest = $number % 1000000; + return self::terbilangBm($millions) . ' juta' . ($rest ? ' ' . self::terbilangBm($rest) : ''); + } + return 'terlalu besar'; + } + + public static function ringgitTerbilang($amount, bool $tambahSahaja = true): string + { + $formatted = number_format((float)$amount, 2, '.', ''); + [$ringgitStr, $senStr] = explode('.', $formatted); + + $ringgit = (int)$ringgitStr; + $sen = (int)$senStr; + + $parts = []; + $parts[] = self::terbilangBm($ringgit) . ' ringgit'; + + if ($sen > 0) { + $parts[] = 'dan ' . self::terbilangBm($sen) . ' sen'; + } elseif ($tambahSahaja) { + $parts[] = 'sahaja'; + } + + return trim(preg_replace('/\s+/', ' ', implode(' ', $parts))); + } } diff --git a/app/Http/Controllers/KhazanahController.php b/app/Http/Controllers/KhazanahController.php index 15b2818..3f9a59c 100644 --- a/app/Http/Controllers/KhazanahController.php +++ b/app/Http/Controllers/KhazanahController.php @@ -4417,4 +4417,274 @@ class KhazanahController extends Controller } -} + public function pampasanDetail($id) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + $cawangan_info = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan']) + ->json(); + + $gadai = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/gadai/norujukan/' . '011237' . '/' . $id) + ->json(); + + $gadai_info = is_array($gadai) && isset($gadai[0]) ? $gadai[0] : $gadai; + + $customer_info = null; + if(isset($gadai_info['nokp'])) { + $customer = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/customers/' . $gadai_info['nokp']) + ->json(); + + $customer_info = null; + if (isset($gadai_info['nokp'])) { + $customer = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/customers/' . $gadai_info['nokp']) + ->json(); + + $customer_info = is_array($customer) && isset($customer[0]) ? $customer[0] : $customer; + } + + + $barang_kes = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/palsu/laporan/', ['kodcaw' => $auth_user['cawangan']]) + ->json(); + + // You may need to adjust the array index if the API returns an array of results + $gadai_info = is_array($gadai) && isset($gadai[0]) ? $gadai[0] : $gadai; + // $pampasan_info = is_array($pampasan) && isset($pampasan[0]) ? $pampasan[0] : $pampasan; + + $barang_kes_collection = collect($barang_kes); + $barang_kes_info = $barang_kes_collection->where('norujukan', '=', $id)->first(); + + $customer_info = null; + if (isset($gadai_info['nokp'])) { + $customer = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/customers/' . $gadai_info['nokp']) + ->json(); + + $customer_info = is_array($customer) && isset($customer[0]) ? $customer[0] : $customer; + } + + $denominasi = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/DenominasiController/' . $auth_user['cawangan'])->json(); + + if (sizeof($denominasi) == 0) { + $denominasi = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/DenominasiCreate/' . $auth_user['cawangan'])->json(); + } else { + $denominasi = $denominasi[0]; + } + + $pampasan = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/pampasan', ['kodcaw' => '011237', 'norujukan' => $id]) + ->json()['data'][0]; + + $baucerno = $pampasan['baucerno']; + $nilaimarhun = $barang_kes_info['nilaimarhun'] ?? 0; + $pembiayaan = $barang_kes_info['pembiayaan'] ?? 0; + $untung = $barang_kes_info['untung'] ?? 0; + + + $jumlah_tebus = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/tebus/norujukan/' . $auth_user['cawangan'] . '/' . $id) + ->json()[0]['bakipjm']; + + $jumlah_pampasan = $nilaimarhun - $pembiayaan - $untung; + + $jumlahPanjar = $jumlah_tebus + $jumlah_pampasan; + + return view('khazanah.pampasan_detail', compact('gadai_info', 'barang_kes_info', 'cawangan_info', 'customer_info', 'baucerno', 'denominasi', 'jumlah_pampasan', 'jumlah_tebus', 'jumlahPanjar')); + } + } + + public function initiatePampasan(Request $request) + { + $norujukan = $request->input('norujukan'); + $teller = auth()->user()->name; + $kodcaw = auth()->user()->cawangan; + $baucerno = $this->generateBaucer($kodcaw); + + $response = Http::post(config('api.url') . '/api/pampasan/initiatePampasan', [ + 'norujukan' => $norujukan, + 'kodcaw' => $kodcaw, + 'teller' => $teller, + 'baucerno' => $baucerno, + ]); + + if ($response->failed()) { + throw new \Exception("HTTP error! status: " . $response->status(), 1); + } + + $result = $response->json(); + + // $jumlah_pampasan = $nilaimarhun - $pembiayaan - $untung; + // $jumlahTebus = $pembiayaan + $untung; + // $jumlahPanjar = $jumlah_pampasan + $jumlahTebus; + + //return view('khazanah.pampasan_detail', compact('gadai_info', 'pampasan_info', 'cawangan_info', 'customer_info','baucerno', 'denominasi','jumlah_pampasan', 'jumlahTebus', 'jumlahPanjar') ); + return response()->json($result); + } + + public function generateBaucer($kodcaw) + { + $data = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url').'/api/SenaraiPanjar/list/' . $kodcaw) + ->json(); + + $today = now(); + $dd = $today->format('d'); + $mm = $today->format('m'); + $yy = $today->format('y'); + + $recno = $data['recno'] ?? 0; + + $baucerno = 'B' . $yy . $mm . $dd . '-' . str_pad($recno, 4, '0', STR_PAD_LEFT); + + return $baucerno; + } + + public function terimaPampasan(Request $request) + { + $responsePampasan = Http::withOptions(['verify' => config('app.api_verify')]) + ->post(config('api.url') . '/api/pampasan/terimaPampasan',[ + "norujukan" => $request->norujukan, + "kodcaw" => auth()->user()->cawangan, + "jumlah_pampasan" => $request->jumlahpampasan, + "teller" => auth()->user()->name, + "denominasi" => $request->denominasi, + ] + )->json(); + + $jumlahTebus = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/tebus/norujukan/' . auth()->user()->cawangan .'/'.$request->norujukan)->json()[0]['bakipjm']; + $bayaranPanjar = $request->jumlahpampasan + $jumlahTebus; + + + $responsePanjar = Http::withOptions(['verify' => config('app.api_verify')]) + ->post( + config('api.url') . '/api/panjar/createpanjar/' . auth()->user()->cawangan, + array_merge( + [ + 'tarikhbil' => now()->format('Y-m-d'), + 'jenismodal' => 'belanjaam', + 'deskripsi' => 'BAYARAN PAMPASAN ' . '(' . $request->norujukan . ')', + 'bayaran' => $bayaranPanjar, + 'kodlaluan' => auth()->user()->name, + 'baucer' => $responsePampasan['data']['baucerno'], + 'tuntutan' => auth()->user()->name + ], + $request->denominasi + + ) + )->json(); + + if ($responsePampasan['success'] == true) { + return redirect()->route('pampasan.resit', ["pampasan" => $responsePampasan['data']]); + } else + return redirect()->route('khazanah.panjar')->with('pampasaninformation', ['status' => 'error', 'message' => 'Baki perubatan tidak mencukupi.']); + } + + public function resitPampasan(Request $request) + { + $pampasan = $request->pampasan; + $kodcaw = $pampasan['kodcaw']; + $norujukan = $pampasan['norujukan'] ?? null; + + if ($norujukan) { + $gadai_info = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/gadai/norujukan/' . $kodcaw . '/' . $norujukan) + ->json(); + + $gadai_info = is_array($gadai_info) && isset($gadai_info[0]) ? $gadai_info[0] : $gadai_info; + + $customer_info = null; + if (isset($gadai_info['nokp'])) { + $customer = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/customers/' . $gadai_info['nokp']) + ->json(); + + $customer_info = is_array($customer) && isset($customer[0]) ? $customer[0] : $customer; + } + + $pampasan_info = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/palsu/laporan/', ['kodcaw' => $kodcaw]) + ->json(); + + $norujukan = $norujukan; + + $pampasan_info = collect($pampasan_info)->firstWhere('norujukan', $norujukan); + + $nilaimarhun = $pampasan_info['nilaimarhun'] ?? 0; + $pembiayaan = $pampasan_info['pembiayaan'] ?? 0; + $untung = $pampasan_info['untung'] ?? 0; + + $jumlah_pampasan = $nilaimarhun - $pembiayaan - $untung; + + $status = Http::withOptions(['verify' => config('app.api_verify')]) + ->put(config('api.url') . '/api/pampasan/updateStatusPampasan', ['kodcaw' => $kodcaw, 'norujukan' => $norujukan]) + ->json(); + + // dd($pampasan_info, $nilaimarhun, $pembiayaan, $untung, $jumlah_pampasan); + + // dd($norujukan); + + return view('print.resit.resitpampasan', compact( + 'pampasan', + 'gadai_info', + 'customer_info', + 'pampasan_info', + 'nilaimarhun', + 'pembiayaan', + 'untung', + 'jumlah_pampasan', + 'status' + )); + } + } + + public function suratPampasan(Request $request, $norujukan) + { + $auth_user = Auth::user(); + + $cawangan_info = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/cawangan/'.$auth_user['cawangan'])->json(); + + $gadai = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/gadai/norujukan/' . '011237' . '/' . $norujukan) + ->json(); + + $gadai_info = is_array($gadai) && isset($gadai[0]) ? $gadai[0] : $gadai; + + $customer_info = null; + if(isset($gadai_info['nokp'])) { + $customer = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/customers/' . $gadai_info['nokp']) + ->json(); + + $customer_info = is_array($customer) && isset($customer[0]) ? $customer[0] : $customer; + } + + $pampasan = Http::withOptions(['verify' => config('app.api_verify')]) + ->get(config('api.url') . '/api/palsu/laporan/' , ['kodcaw'=>'011237']) + ->json(); + + $pampasan_collection = collect($pampasan); + + $pampasan_info = $pampasan_collection->where('norujukan', '=', $norujukan)->first(); + + + if (!$pampasan_info) { + abort(404, 'Maklumat pampasan tidak dijumpai untuk no rujukan tersebut.'); + } + + $nilaimarhun = $pampasan_info['nilaimarhun'] ?? 0; + $pembiayaan = $pampasan_info['pembiayaan'] ?? 0; + $untung = $pampasan_info['untung'] ?? 0; + + $jumlah_pampasan = $nilaimarhun - $pembiayaan - $untung; + $jumlah = $pampasan_info['jumlah_pampasan'] ?? 0; + $jumlah_pampasan_terbilang = Helper::ringgitTerbilang($jumlah_pampasan); + + return view('print.surat_pampasan', compact('cawangan_info', 'gadai', 'gadai_info', 'customer_info', 'pampasan', 'pampasan_info','jumlah_pampasan_terbilang', 'jumlah_pampasan')); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/OperasiController.php b/app/Http/Controllers/OperasiController.php index 1b8872f..2bc4fc1 100644 --- a/app/Http/Controllers/OperasiController.php +++ b/app/Http/Controllers/OperasiController.php @@ -92,11 +92,17 @@ class OperasiController extends Controller 'siri' => $request->siri ])->json(); - $updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $request->kodcaw . '/' . $norujukan,[ + $updateData = [ 'sahkan' => 1, 'namaoperasi' => $request->namaoperasi, 'siri' => $request->siri - ])->json(); + ]; + + if ($request->has('actions')) { + $updateData['actions'] = $request->actions; + } + + $updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $request->kodcaw . '/' . $norujukan, $updateData)->json(); }else{ $updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateHapusAnsuran',[ 'siri' => $request->siri, @@ -148,6 +154,49 @@ class OperasiController extends Controller return response()->json($updatelulus,200); } + public function createKelulusanByKhazanah(Request $request) + { + $auth_user = Auth::user(); + $api_url = config('api.url'); + + $current = Carbon::now(); + $current = new Carbon(); + + $norujukan = $request->norujukan; + + $cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json(); + + $getsiri = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/ListLatestLulus/'. $auth_user['cawangan'] . '/' . $norujukan)->json(); + + if(isset($getsiri['siri'])) + { + $siri = $getsiri['siri'] + 1; + }else{ + $siri = 1; + } + + $createlulus = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/CreateKelulusan/' . $auth_user['cawangan'] . '/' . $norujukan . '/roles/khazanah', [ + 'komen' => $request->komen, + 'dategadai' => $current->toDateString(), + 'bilgadai' => 1, + 'siri' => $siri, + 'margin' => $request->margin, + 'berat' => $request->berat, + 'nilaimarhun' => $request->nilaimarhun, + 'status' => $request->status, + 'jumpinjam' => $request->jumpinjam, + 'jenistebus' => "G", + 'teller' => $request->teller, + 'peloperasi' => "operasi", + 'pelulus' => "operasi", + 'actions' => "Mohon Pengesahan Pembayaran Pampasan" + ])->json(); + + event(new OperasiNotice($auth_user['cawangan'],$auth_user['name'])); + + return response()->json($siri,201); + } + public function createkelulusan(Request $request) { $auth_user = Auth::user(); diff --git a/app/Http/Controllers/PenebusanController.php b/app/Http/Controllers/PenebusanController.php index 652b7e7..32ef7f7 100644 --- a/app/Http/Controllers/PenebusanController.php +++ b/app/Http/Controllers/PenebusanController.php @@ -46,7 +46,10 @@ class PenebusanController extends Controller $nilaihargasemasa = $this->tukaranhargaemas($norujukan); $pertambahpinjaman = 0.80; - return view('penebusan.' . $cawangan_info['version'] . '.index',compact('cawangan_info','api_url','gadai','marhun','nama','nilaihargasemasa','pertambahpinjaman')); + + $pampasan = $this->getPampasanByNorujukan($norujukan); + + return view('penebusan.' . $cawangan_info['version'] . '.index',compact('cawangan_info','api_url','gadai','marhun','nama','nilaihargasemasa','pertambahpinjaman', 'pampasan')); } public function tebuspenuh(Request $request) @@ -786,4 +789,26 @@ class PenebusanController extends Controller return view($view, compact('cawangan_info','api_url','gadai','marhun','nama','nilaihargasemasa')); } + public function getPampasanByNorujukan($norujukan) + { + $auth_user = Auth::user(); + + $pampasanListResponse = Http::get(config('api.url'). '/api/palsu/laporan', [ + 'kodcaw' => $auth_user['cawangan'], + 'status' => 'all', + ]); + + if($pampasanListResponse->failed()){ + throw new \Exception("Something wrong with API", 1); + } + + $pampasanList = array_filter($pampasanListResponse->json(), function($pampasan) use($norujukan){ + return $pampasan['norujukan'] == $norujukan; + }); + + $pampasan = sizeof($pampasanList) == 0 ? null : array_pop($pampasanList); + + return $pampasan; + } + } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 37bb7be..7356ee1 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -72,5 +72,6 @@ class Kernel extends HttpKernel 'admin' => 'App\Http\Middleware\Admin', 'audit' => 'App\Http\Middleware\Audit', 'masteradmin' => 'App\Http\Middleware\Masteradmin', + 'role' => 'App\Http\Middleware\RoleAccess', ]; } diff --git a/app/Http/Middleware/RoleAccess.php b/app/Http/Middleware/RoleAccess.php new file mode 100644 index 0000000..74c33c9 --- /dev/null +++ b/app/Http/Middleware/RoleAccess.php @@ -0,0 +1,71 @@ +roles; + $userRoleHarian = $user->role_harian ?? null; + + // Check each allowed role + foreach ($roles as $role) { + switch ($role) { + case 'teller': + if ($userRoleHarian == 'teller' || $userRole == 'teller') { + return $next($request); + } + break; + + case 'khazanah': + if ($userRole == 'pc' || $userRole == 'ppc') { + return $next($request); + } + break; + + case 'admin': + if ($userRole == 'admin') { + return $next($request); + } + break; + + case 'penilai': + if ($userRole == 'penilai') { + return $next($request); + } + break; + + case 'operasi': + if ($userRole == 'operasi') { + return $next($request); + } + break; + + case 'audit': + if ($userRole == 'audit') { + return $next($request); + } + break; + } + } + + // If no roles matched, deny access + abort(403, 'Access denied. Required roles: ' . implode(', ', $roles)); + } +} \ No newline at end of file diff --git a/resources/js/app.js b/resources/js/app.js new file mode 100644 index 0000000..2dee074 --- /dev/null +++ b/resources/js/app.js @@ -0,0 +1,30 @@ +/** + * First we will load all of this project's JavaScript dependencies which + * includes Vue and other libraries. It is a great starting point when + * building robust, powerful web applications using Vue and Laravel. + */ + +require('./bootstrap'); + +window.Vue = require('vue'); + +/** + * The following block of code may be used to automatically register your + * Vue components. It will recursively scan this directory for the Vue + * components and automatically register them with their "basename". + * + * Eg. ./components/ExampleComponent.vue -> + */ + +// const files = require.context('./', true, /\.vue$/i) +// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default)) + +/** + * Next, we will create a fresh Vue application instance and attach it to + * the page. Then, you may begin adding components to this application + * or customize the JavaScript scaffolding to fit your unique needs. + */ + +const app = new Vue({ + el: '#app', +}); \ No newline at end of file diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js index 937d7b9..61a0929 100644 --- a/resources/js/bootstrap.js +++ b/resources/js/bootstrap.js @@ -35,7 +35,7 @@ window.Pusher = require('pusher-js'); window.Echo = new Echo({ broadcaster: 'pusher', - key: '26b0ec2f297f94b7aa9b', - cluster: 'ap1', - forceTLS: true + key: process.env.MIX_PUSHER_APP_KEY, + cluster: process.env.MIX_PUSHER_APP_CLUSTER, + forceTLS: false }); diff --git a/resources/views/khazanah/pampasan_detail.blade.php b/resources/views/khazanah/pampasan_detail.blade.php new file mode 100644 index 0000000..3059e8b --- /dev/null +++ b/resources/views/khazanah/pampasan_detail.blade.php @@ -0,0 +1,282 @@ +@extends('layouts.app') + +@section('content') +
+

PAMPASAN

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + @php + $nilaimarhun = floatval($barang_kes_info['nilaimarhun'] ?? 0); + $pembiayaan = floatval($barang_kes_info['pembiayaan'] ?? 0); + $untung = floatval($barang_kes_info['untung'] ?? 0); + $jumlah_pampasan = $nilaimarhun - $pembiayaan - $untung; + @endphp + +
+
+ + +
+ +
+
+ + +
+
+ +
+
+
+
+ Cara Pengiraan Jumlah Pampasan:
+ + Jumlah Pampasan = Nilai Marhun - Baki Pembiayaan - Keuntungan + +
+
+
+
+
+ + + +
+
+
+
+ + + + @include('modal.denopampasan') +@endsection diff --git a/resources/views/khazanah/panjar.blade.php b/resources/views/khazanah/panjar.blade.php index c144ae3..a478c57 100644 --- a/resources/views/khazanah/panjar.blade.php +++ b/resources/views/khazanah/panjar.blade.php @@ -9,38 +9,55 @@
- + +
@if(Session::has('messageinformation')) @php - $session = Session::get("messageinformation"); + $session = Session::get("messageinformation"); @endphp - @endif - -
-
-
-
-
-
+ + @if(Session::has('pampasaninformation')) + @php + $session = Session::get("pampasaninformation"); + @endphp + + @endif + + -
+
@@ -54,34 +71,62 @@
-
+
- - - - - - + + + + + + - + @if(isset($cawangan_info['kodcaw']) && $cawangan_info['kodcaw'] === '011237') + + @endif + +
- - - - - - - - - - - -
biltarikhdeskripsikategoribayarantindakan
+ +
+ + + + + + + + + + + +
biltarikhdeskripsikategoribayarantindakan
+
+ +
- +
@@ -89,44 +134,40 @@
-@endsection + +@endsection \ No newline at end of file diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 777e5ed..69c9697 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -39,12 +39,12 @@ + - diff --git a/resources/views/modal/denopampasan.blade.php b/resources/views/modal/denopampasan.blade.php new file mode 100644 index 0000000..8253c05 --- /dev/null +++ b/resources/views/modal/denopampasan.blade.php @@ -0,0 +1,199 @@ + + + diff --git a/resources/views/modal/panjar.blade.php b/resources/views/modal/panjar.blade.php index e0ea373..053fb51 100644 --- a/resources/views/modal/panjar.blade.php +++ b/resources/views/modal/panjar.blade.php @@ -1,4 +1,4 @@ - + - - \ No newline at end of file + + + + diff --git a/resources/views/operasi/kelulusan.blade.php b/resources/views/operasi/kelulusan.blade.php index 399628d..a521f97 100644 --- a/resources/views/operasi/kelulusan.blade.php +++ b/resources/views/operasi/kelulusan.blade.php @@ -2,27 +2,97 @@ @section('content') -