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
+
+
+
+
+
+
+
+ Cara Pengiraan Jumlah Pampasan:
+
+ Jumlah Pampasan = Nilai Marhun - Baki Pembiayaan - Keuntungan
+
+
+
+
+
+
+
+ DENO
+
+
+ BATAL
+
+
+
+
+
+
+
+ @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 @@
-
+
- Home
- Panjar
+ Home
+ Panjar
-
+
@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
+
+
-
+
-
+
- Keraian
- Selenggara
- Belanja Am
- Perubatan
- Dapur
- Pos
+ Keraian
+ Selenggara
+ Belanja Am
+ Perubatan
+ Dapur
+ Pos
- Baki Perubatan
+ @if(isset($cawangan_info['kodcaw']) && $cawangan_info['kodcaw'] === '011237')
+ Pampasan
+ @endif
+
+ Baki Perubatan
-
-
-
- bil
- tarikh
- deskripsi
- kategori
- bayaran
- tindakan
-
-
-
+
+
+
+
+
+ bil
+ tarikh
+ deskripsi
+ kategori
+ bayaran
+ tindakan
+
+
+
+
+
+
+
+
+
+
+ bil
+ nokp
+ norujukan
+ pembiayaan
+ nilai marhun
+ jbg
+ status
+ tindakan
+
+
+
+
+
+
+
-
+
@@ -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')
-
-
-
-
-
-
-
-
-
-
- Nama :
-
-
+
+
+
+
+
+
+
-
-
Kad Pengenalan :
-
+
+
+ Nombor Rujukan :
+
+
+
+
+
+ Nama :
+
+
+
+
+ Kad Pengenalan :
+
+
+
+
+
+
+
+
+
+
+ Nilai Marhun
+ text
+
+
+ Baki Pembiayaan
+
+
+
+ Jumlah Pampasan
+
+
+
+ Keuntungan
+
+
+
+ Ansuran Pembiayaan
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Nama :
+
+
+
+
+ Kad Pengenalan :
+
+
@@ -71,404 +141,459 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home
+ Kelulusan
+
+
+
+
+
+
+
+
+
+
+ No Rujukan
+ Cawangan
+ Teller
+ Komen
+ Status
+ Nilai Pembiayaan
+ Ansuran
+ Nilai Marhun
+ Berat
+ Margin
+ Tindakan
+
+
+
+ @foreach($arraykelulusan as $index=>$k)
+
+ @php
+ $targetModal = '#kelulusanmodal';
+ $targetModal = strtolower($k['status']) == 'kelulusan pengeluaran pampasan' ? '#kelulusan_pampasan_modal' : $targetModal;
+
+ @endphp
+ {{ $k['norujukan'] }}
+ {{ $k['cawangan'] }}
+ {{ $k['namateller'] }}
+ {{ $k['komen'] }}
+ {{ $k['status'] }}
+ {{ number_format($k['pinjaman'],2) }}
+ @if(isset($k['ansuran']) && $k['ansuran'] != 0)
+ {{ number_format($k['ansuran'],2) }}
+ @else
+
+ @endif
+ {{ $k['nilaimarhun'] }}
+ {{ $k['berat'] }}
+ {{ $k['margin'] }}
+
+
+
+
+ @endforeach
+
+
+
+
+
-
-
-
-
-
-
-
-
-
- Home
- Kelulusan
-
-
-
-
-
-
-
-
-
-
- No Rujukan
- Cawangan
- Teller
- Komen
- Status
- Nilai Pembiayaan
- Ansuran
- Nilai Marhun
- Berat
- Margin
- Tindakan
-
-
-
- @foreach($arraykelulusan as $index=>$k)
-
- {{ $k['norujukan'] }}
- {{ $k['cawangan'] }}
- {{ $k['namateller'] }}
- {{ $k['komen'] }}
- {{ $k['status'] }}
- {{ number_format($k['pinjaman'],2) }}
- @if(isset($k['ansuran']) && $k['ansuran'] != 0)
- {{ number_format($k['ansuran'],2) }}
- @else
-
- @endif
- {{ $k['nilaimarhun'] }}
- {{ $k['berat'] }}
- {{ $k['margin'] }}
-
-
-
- @endforeach
-
-
-
-
-
-
-
-
-
-@endsection
+@endsection
\ No newline at end of file
diff --git a/resources/views/penebusan/v2/index.blade.php b/resources/views/penebusan/v2/index.blade.php
index 4d05f39..c3d88f2 100644
--- a/resources/views/penebusan/v2/index.blade.php
+++ b/resources/views/penebusan/v2/index.blade.php
@@ -131,6 +131,20 @@
+ @if($pampasan)
+
+ @endif
+
@@ -1082,6 +1096,28 @@
+
+
+
+
@endsection
diff --git a/resources/views/print/laporan_tebus_ujrah.blade.php b/resources/views/print/laporan_tebus_ujrah.blade.php
index e19f8a8..9840896 100644
--- a/resources/views/print/laporan_tebus_ujrah.blade.php
+++ b/resources/views/print/laporan_tebus_ujrah.blade.php
@@ -440,9 +440,12 @@
{{ number_format($totalnm, 2) }}
{{ number_format($totalpinjamanasal, 2) }}
{{ number_format($totalpinjaman, 2) }}
- @php$totalkeuntunganrebet = $totalpinjaman + $totalupah - $totalbayaran;
- echo number_format($totalkeuntunganrebet, 2);
- @endphp ?>
+
+ @php
+ $totalkeuntunganrebet = $totalpinjaman + $totalupah - $totalbayaran;
+ echo number_format($totalkeuntunganrebet, 2);
+ @endphp
+
{{ number_format($totalujrah, 2) }}
{{ number_format($totalonepercent, 2) }}
{{ number_format($totalupah, 2) }}
diff --git a/resources/views/print/resit/resitpampasan.blade.php b/resources/views/print/resit/resitpampasan.blade.php
new file mode 100644
index 0000000..1875549
--- /dev/null
+++ b/resources/views/print/resit/resitpampasan.blade.php
@@ -0,0 +1,258 @@
+
+
+
+
+ Resit Pampasan
+
+
+
+
+
+
+
+
+
+
+
+ Nama:
+ {{ $customer_info['nama'] }}
+
+
+ No. KP:
+ {{ $gadai_info['nokp'] }}
+
+
+ No. SAG:
+ {{ $pampasan['norujukan'] }}
+
+
+ Tarikh Tuntutan:
+ {{ \Carbon\Carbon::parse($pampasan['created_at'])->format('d/m/Y') }}
+
+
+
+
+
+
+
+ Nilai Marhun:
+ RM {{ number_format($pampasan_info['nilaimarhun'], 2) }}
+
+
+ (-) Baki Pembiayaan:
+ RM {{ number_format($pampasan_info['pembiayaan'], 2) }}
+
+
+ (-) Keuntungan:
+ RM {{ number_format($pampasan_info['untung'], 2) }}
+
+
+ JUMLAH PAMPASAN
+ RM {{ number_format($pampasan['jumlah_pampasan'], 2) }}
+
+
+
+
+
+
__________________________
+
PELANGGAN
+
{{ $customer_info['nama'] }}
+
+
+
__________________________
+
AR-RAHN
+
{{ auth()->user()->name }}
+
+
+
+
+
+
+
+
+
+ Nama:
+ {{ $customer_info['nama'] }}
+
+
+ No. KP:
+ {{ $gadai_info['nokp'] }}
+
+
+ No. SAG:
+ {{ $pampasan['norujukan'] }}
+
+
+ Tarikh Tuntutan:
+ {{ \Carbon\Carbon::parse($pampasan['created_at'])->format('d/m/Y') }}
+
+
+
+
+
+
+ Nilai Marhun:
+ RM {{ number_format($pampasan_info['nilaimarhun'], 2) }}
+
+
+ (-) Baki Pembiayaan:
+ RM {{ number_format($pampasan_info['pembiayaan'], 2) }}
+
+
+ (-) Keuntungan:
+ RM {{ number_format($pampasan_info['untung'], 2) }}
+
+
+ JUMLAH PAMPASAN
+ RM {{ number_format($pampasan['jumlah_pampasan'], 2) }}
+
+
+
+
+
+
__________________________
+
PELANGGAN
+
{{ $customer_info['nama'] }}
+
+
+
__________________________
+
AR-RAHN
+
{{ auth()->user()->name }}
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/print/surat_pampasan.blade.php b/resources/views/print/surat_pampasan.blade.php
new file mode 100644
index 0000000..c0756d4
--- /dev/null
+++ b/resources/views/print/surat_pampasan.blade.php
@@ -0,0 +1,278 @@
+
+
+
+
+
+ Surat Pampasan
+
+
+
+
+
+
+
+
+
+
+
AKUAN TERIMAAN PAMPASAN DAN PELEPASAN
+
+
NO. TUNTUTAN : {{ $gadai_info['norujukan'] }}
+
+
+
+ 1. Bahawasanya saya, Penama : {{ $customer_info['nama'] }}
+ No. Kad Pengenalan : {{ $customer_info['kpbaru'] }}
+ Adalah dengan ini atas BALASAN sebanyak RM {{ number_format($jumlah_pampasan, 2) }}
+ (Ringgit Malaysia : {{ $jumlah_pampasan_terbilang }} sahaja)
+ yang dibayar kepada saya oleh AR-RAHN CAWANGAN SEMPORNA atau
+ KOPERASI PERMODALAN KELANTAN BERHAD (KoPKB) yang mana penerimaan wang bayaran tersebut
+ adalah saya perakui sebagai bayaran muktamad melepaskan AR-RAHN CAWANGAN SEMPORNA
+ atau KOPERASI PERMODALAN KELANTAN BERHAD (KoPKB) daripada segala liabiliti, tindakan, klausa
+ tindakan, tuntutan dan tanggungjawab yang saya boleh kuatkuasakan, punyai atau mungkin mempunyai
+ pada masa ini atau pada bila-bila masa terhadap AR-RAHN CAWANGAN SEMPORNA , KOPERASI PERMODALAN
+ KELANTAN BERHAD (KoPKB)
+ berkait dengan kehilangan/kecurian barangan kemas pada bulan November 2024 yang
+ telah digadaikan di AR-RAHN CAWANGAN SEMPORNA, LOT F9-0 GROUND FLOOR, BANDAR MUTIARA, JALAN HOSPITAL,
+ 91300 SEMPORNA, SABAH atau apa-apa perkara
+ yang timbul berkait/akibat
+ daripada kehilangan/kecurian tersebut.
+
+
+
+ 2. DAN saya memberikan sebenar-benar akujanji bahawa saya tidak akan
+ mengambil/memulakan
+ sebarang tindakan perundangan terhadap AR-RAHN CAWANGAN SEMPORNA atau
+ KOPERASI PERMODALAN KELANTAN BERHAD (KoPKB) berkait dengan kehilangan/kecurian tersebut
+ dengan penerimaan wang balasan di atas.
+
+
+
+ Adalah saya dengan ini memperakui bahawa dokumen ini telah dibacakan/saya baca dan saya fahami
+ kesan dan implikasi dokumen ini sepenuh-penuhnya.
+
+
+
+ Bertarikh:
+
+
+
+
+
+
(PELANGGAN)
+
{{ $customer_info['nama'] }}
+
No K/P:
+
+
+
+
(SAKSI)
+
Nama :
+
No K/P:
+
+
+
+
+
+
+ Cetak
+
+
+
+
+
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index af251bc..0fdef70 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -1,5 +1,6 @@
'khazanah.capaian','uses'=>'KhazanahController@capa
Route::get('/alirantunai',['as'=>'khazanah.alirantunai','uses'=>'KhazanahController@alirantunai'])->middleware('auth','khazanah');
Route::get('/pelangganan',['as'=>'khazanah.pelangganan','uses'=>'KhazanahController@pelanggan'])->middleware('auth','khazanah');
Route::get('/bajet',['as'=>'khazanah.bajet','uses'=>'KhazanahController@bajet'])->middleware('auth','khazanah');
-//Route::get('/panjar',['as'=>'khazanah.panjar','uses'=>'KhazanahController@panjar'])->middleware('auth','khazanah');
+Route::get('/panjar',['as'=>'khazanah.panjar','uses'=>'KhazanahController@panjar'])->middleware('auth','khazanah');
Route::get('/getkelulusan',['as'=>'khazanah.getkelulusan','uses'=>'KhazanahController@getkelulusan'])->middleware('auth','teller');
Route::post('/createkelulusan',['as'=>'khazanah.createkelulusan','uses'=>'KhazanahController@createkelulusan'])->middleware('auth','teller');
Route::put('/updatekelulusan',['as'=>'khazanah.updatekelulusan','uses'=>'KhazanahController@updatekelulusan'])->middleware('auth','khazanah');
@@ -335,6 +336,7 @@ Route::post('/barcodescanned',['as'=>'barcode.scanned','uses'=>'KhazanahControll
//Operasi
Route::get('/operasi/kelulusan','OperasiController@kelulusan')->name('operasi.kelulusan')->middleware('auth','operasi');
Route::post('/operasi/createkelulusan',['as'=>'operasi.createkelulusan','uses'=>'OperasiController@createkelulusan'])->middleware('auth','teller');
+Route::post('/operasi/createkelulusan-by-khazanah',['as'=>'operasi.createkelulusan-by-khazanah','uses'=>'OperasiController@createkelulusanByKhazanah'])->middleware('auth', 'khazanah');
Route::get('/operasi/getkelulusan',['as'=>'operasi.getkelulusan','uses'=>'OperasiController@getkelulusan'])->middleware('auth','teller');
Route::put('/operasi/updatekelulusan',['as'=>'operasi.updatekelulusan','uses'=>'OperasiController@updatekelulusan'])->middleware('auth','operasi');
Route::get('/operasi/parameter','OperasiController@parameter')->name('parameter')->middleware('auth','operasi');
@@ -492,3 +494,20 @@ Route::get('/event/tellercash',['as'=>'event.tellercash','uses'=>'EventTriggerCo
Route::get('/perubatan',['as'=>'perubatan','uses'=>'PerubatanController@index'])->middleware('auth','operasi');
Route::get('/perubatan/search',['as'=>'perubatan.search','uses'=>'PerubatanController@search'])->middleware('auth','operasi');
Route::put('/perubatan/update',['as'=>'perubatan.update','uses'=>'PerubatanController@update'])->middleware('auth','operasi');
+
+/* Pampasan */
+
+//Page Pampasan Detail Payment Customer
+Route::get('/pampasan/detail/{norujukan}', ['as' => 'pampasan.detail','uses' => 'KhazanahController@pampasanDetail'])->middleware('auth', 'khazanah');
+
+//Selepas teller print surat perjanjian pampasan pelanggan
+Route::post('/pampasan/initiate',['as' => 'pampasan.initiate', 'uses' => 'KhazanahController@initiatePampasan'])->middleware('auth', 'teller');
+
+//Selepas PC masukkan Deno dan Submit Jumlah Pampasan
+Route::post('/pampasan/terima',['as' => 'pampasan.terima', 'uses' => 'KhazanahController@terimaPampasan'])->middleware('auth', 'khazanah');
+
+//Cetak Resit Pampasan
+Route::get(('/pampasan/resit'), ['as' => 'pampasan.resit', 'uses' => 'KhazanahController@resitPampasan'])->middleware('auth', 'khazanah');
+
+//Surat Pampasan
+Route::get('/pampasan/surat/{norujukan}', ['as' => 'pampasan.surat', 'uses' => 'KhazanahController@suratPampasan'])->middleware('auth', 'role:teller,khazanah');
\ No newline at end of file