Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca2a02e354 | |||
| 76176ed453 | |||
| 17a5bfafdd | |||
| 5f29f064a0 | |||
| 9dae32a462 | |||
| c437a3f504 | |||
| b41234e10b | |||
| b7d217948c | |||
| 2d282897fc | |||
| 94f8f6e855 | |||
| 72108d3f87 | |||
| 3a64cc2400 | |||
| 1d71a31078 | |||
| 8e19d0488a | |||
| 918502b504 | |||
| 8a2bae7a88 | |||
| 67af37a1cd | |||
| 3f6fb8d985 | |||
| 371e4d8168 | |||
| 5d421760af |
+50
@@ -0,0 +1,50 @@
|
|||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=production
|
||||||
|
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=https://annurv2.erahn.com.my
|
||||||
|
API_URL=https://apiannurv2.erahn.com.my
|
||||||
|
API_ARRAHNBID=http://lelong.test/api/
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=192.168.1.216
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=kaunter_annur
|
||||||
|
DB_USERNAME=spider
|
||||||
|
DB_PASSWORD=arrahn@123
|
||||||
|
|
||||||
|
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
|
||||||
+3
-1
@@ -51,4 +51,6 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
|||||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
MYKAD_READER_PORT=8085
|
MYKAD_READER_PORT=8085
|
||||||
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
|
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
|
||||||
|
|
||||||
|
INTERNAL_NOTIFICATION_SECRET=erahn-local-notification-secret
|
||||||
+4
-2
@@ -1,10 +1,10 @@
|
|||||||
APP_NAME=Laravel
|
APP_NAME=Laravel
|
||||||
APP_ENV=local
|
APP_ENV=local
|
||||||
|
APP_VERSION=v3.3
|
||||||
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
API_URL=http://localhost:8000
|
API_URL=http://localhost:8000
|
||||||
API_ARRAHNBID=http://lelong.test/api/
|
|
||||||
|
|
||||||
LOG_CHANNEL=stack
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
@@ -47,4 +47,6 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
|||||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
MYKAD_READER_PORT=17321
|
MYKAD_READER_PORT=17321
|
||||||
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
|
MYKAD_READER_ENABLED_CAWANGAN=''
|
||||||
|
|
||||||
|
INTERNAL_NOTIFICATION_SECRET=
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=production
|
||||||
|
APP_VERSION=v3.3
|
||||||
|
APP_KEY=base64:WRTHcFTq5YARKVdA8YDUzsh9Ue8vD63ivgZgXNNBiGo=
|
||||||
|
APP_DEBUG=false
|
||||||
|
APP_URL=https://ujrah.erahn.com.my
|
||||||
|
API_URL=https://apiujrah.erahn.com.my
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=192.168.1.216
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=kaunter_erahn
|
||||||
|
DB_USERNAME=spider
|
||||||
|
DB_PASSWORD=arrahn@123
|
||||||
|
|
||||||
|
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=17321
|
||||||
|
MYKAD_READER_ENABLED_CAWANGAN=''
|
||||||
|
|
||||||
|
INTERNAL_NOTIFICATION_SECRET="nIDTe(u@6[)VLJyd"
|
||||||
+3
-1
@@ -55,4 +55,6 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
|||||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
MYKAD_READER_PORT=17321
|
MYKAD_READER_PORT=17321
|
||||||
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
|
MYKAD_READER_ENABLED_CAWANGAN=''
|
||||||
|
|
||||||
|
INTERNAL_NOTIFICATION_SECRET=staging_noti_secret
|
||||||
@@ -9,13 +9,7 @@ CREATE USER 'kaunteruser'@'localhost' IDENTIFIED BY 'your_password';
|
|||||||
|
|
||||||
GRANT ALL PRIVILEGES ON kaunter_erahn.* TO 'kaunteruser'@'%';
|
GRANT ALL PRIVILEGES ON kaunter_erahn.* TO 'kaunteruser'@'%';
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
```
|
```
|
||||||
|
|
||||||
# ADDITIONAL NOTE
|
|
||||||
|
|
||||||
## customers/v2/index.blade.php is modal to register customer
|
|
||||||
|
|
||||||
## Min Komoditi = RM5000
|
|
||||||
|
|
||||||
# System Flowchart
|
# System Flowchart
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,10 @@ class AdminFeatureController extends Controller
|
|||||||
|
|
||||||
$metaRes = $this->api()->get($api_url . '/api/features');
|
$metaRes = $this->api()->get($api_url . '/api/features');
|
||||||
$meta = $metaRes->successful() ? $metaRes->json() : [];
|
$meta = $metaRes->successful() ? $metaRes->json() : [];
|
||||||
$keys = is_array($meta) && !empty($meta['keys']) ? $meta['keys'] : ['pembiayaan_online'];
|
$keys = is_array($meta) && !empty($meta['keys']) ? $meta['keys'] : ['pembiayaan_online', 'rebet_annur'];
|
||||||
$labels = is_array($meta) && !empty($meta['labels']) ? $meta['labels'] : [
|
$labels = is_array($meta) && !empty($meta['labels']) ? $meta['labels'] : [
|
||||||
'pembiayaan_online' => 'Pembiayaan Online',
|
'pembiayaan_online' => 'Pembiayaan Online',
|
||||||
|
'rebet_annur' => 'Rebet / diskaun Annur',
|
||||||
];
|
];
|
||||||
|
|
||||||
$listRes = $this->api()->get($api_url . '/api/features/cawangan');
|
$listRes = $this->api()->get($api_url . '/api/features/cawangan');
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Events\SerahanPenilai;
|
|||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Services\CustomerService;
|
use App\Services\CustomerService;
|
||||||
|
use App\Services\NotificationService;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@@ -22,6 +23,9 @@ use Illuminate\Support\Facades\Log;
|
|||||||
|
|
||||||
class GadaianController extends Controller
|
class GadaianController extends Controller
|
||||||
{
|
{
|
||||||
|
const MIN_PINJAMAN = 5.00;
|
||||||
|
const MAX_PINJAMAN = 50000.00;
|
||||||
|
|
||||||
public $AliranTunaiController;
|
public $AliranTunaiController;
|
||||||
public $customerService;
|
public $customerService;
|
||||||
|
|
||||||
@@ -32,14 +36,120 @@ class GadaianController extends Controller
|
|||||||
$this->AliranTunaiController = new AliranTunaiController();
|
$this->AliranTunaiController = new AliranTunaiController();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isPembiayaanOnlineEnabled($kodcaw)
|
protected function isFeatureEnabled($kodcaw, $feature)
|
||||||
{
|
{
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
->get(config('api.url') . '/api/cawangan/' . $kodcaw)
|
->get(config('api.url') . '/api/cawangan/' . $kodcaw)
|
||||||
->json();
|
->json();
|
||||||
$features = is_array($cawangan_info) ? ($cawangan_info['features'] ?? []) : [];
|
$features = is_array($cawangan_info) ? ($cawangan_info['features'] ?? []) : [];
|
||||||
|
|
||||||
return !empty($features['pembiayaan_online']);
|
return !empty($features[$feature]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isPembiayaanOnlineEnabled($kodcaw)
|
||||||
|
{
|
||||||
|
return $this->isFeatureEnabled($kodcaw, 'pembiayaan_online');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inbox row for PC at this branch. Failures must not block gadai.
|
||||||
|
*/
|
||||||
|
protected function notifyPcPembiayaanOnlinePending($auth_user, Request $request, $pinjamanAmt)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
app(NotificationService::class)->notifyRoleAtCawangan('pc', $auth_user['cawangan'], [
|
||||||
|
'type' => NotificationService::TYPE_PEMBIAYAAN_PENDING_PC,
|
||||||
|
'title' => 'Pembiayaan online menunggu semakan',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s — %s (RM %s)',
|
||||||
|
$request->nama_pelanggan,
|
||||||
|
$request->norujukan_gadai,
|
||||||
|
number_format((float) $pinjamanAmt, 2)
|
||||||
|
),
|
||||||
|
'url' => route('pembiayaan.online.pc'),
|
||||||
|
'data' => [
|
||||||
|
'norujukan' => $request->norujukan_gadai,
|
||||||
|
'nama_pelanggan' => $request->nama_pelanggan,
|
||||||
|
'pinjaman' => $pinjamanAmt,
|
||||||
|
'created_by' => $auth_user['name'],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Pembiayaan online PC notification failed: '.$e->getMessage(), [
|
||||||
|
'norujukan' => $request->norujukan_gadai,
|
||||||
|
'cawangan' => $auth_user['cawangan'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function parseMoney($value)
|
||||||
|
{
|
||||||
|
if ($value === null || $value === '') {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cleaned = preg_replace('/[^0-9.\-]/', '', str_replace([',', '%', ' '], '', (string) $value));
|
||||||
|
|
||||||
|
return is_numeric($cleaned) ? (float) $cleaned : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function normalizeBorangOnlineFields($norujukan, $pinjaman, $kodbank, $noakaun, $namaAkaun)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'norujukan' => trim((string) $norujukan),
|
||||||
|
'pinjaman' => number_format((float) $this->parseMoney($pinjaman), 2, '.', ''),
|
||||||
|
'kodbank' => strtoupper(trim((string) $kodbank)),
|
||||||
|
'noakaun' => preg_replace('/\s+/', '', (string) $noakaun),
|
||||||
|
'nama_akaun' => strtoupper(trim((string) $namaAkaun)),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function borangOnlineFingerprint(array $fields)
|
||||||
|
{
|
||||||
|
return sha1(implode('|', [
|
||||||
|
$fields['norujukan'],
|
||||||
|
$fields['pinjaman'],
|
||||||
|
$fields['kodbank'],
|
||||||
|
$fields['noakaun'],
|
||||||
|
$fields['nama_akaun'],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function markBorangOnlinePrinted(array $fields)
|
||||||
|
{
|
||||||
|
Session::put('borang_online_printed', array_merge($fields, [
|
||||||
|
'fingerprint' => $this->borangOnlineFingerprint($fields),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasMatchingBorangOnlinePrint(Request $request)
|
||||||
|
{
|
||||||
|
$printed = $request->session()->get('borang_online_printed');
|
||||||
|
if (!is_array($printed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norujukan = (string) $request->input('norujukan_gadai', $request->input('norujukan'));
|
||||||
|
$fields = $this->normalizeBorangOnlineFields(
|
||||||
|
$norujukan,
|
||||||
|
$request->input('pinjaman'),
|
||||||
|
$request->input('kodbank'),
|
||||||
|
$request->input('noakaun'),
|
||||||
|
$request->input('nama_akaun') ?: $request->input('nama_pelanggan')
|
||||||
|
);
|
||||||
|
|
||||||
|
return ($printed['norujukan'] ?? '') === $fields['norujukan']
|
||||||
|
&& ($printed['fingerprint'] ?? '') === $this->borangOnlineFingerprint($fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function borangOnlinePrintedFor($norujukan)
|
||||||
|
{
|
||||||
|
$printed = Session::get('borang_online_printed');
|
||||||
|
if (!is_array($printed) || ($printed['norujukan'] ?? '') !== (string) $norujukan) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
@@ -69,6 +179,7 @@ class GadaianController extends Controller
|
|||||||
Session::put('nokp', $noic);
|
Session::put('nokp', $noic);
|
||||||
Session::put('nopelanggan', $customer_info['nopelanggan']);
|
Session::put('nopelanggan', $customer_info['nopelanggan']);
|
||||||
Session::put('page_reload', true);
|
Session::put('page_reload', true);
|
||||||
|
Session::forget('borang_online_printed');
|
||||||
$gadai = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/gadai/' . $auth_user['cawangan'], [
|
$gadai = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/gadai/' . $auth_user['cawangan'], [
|
||||||
'norujukan' => $norujukan,
|
'norujukan' => $norujukan,
|
||||||
'nopelanggan' => $customer_info['nopelanggan'],
|
'nopelanggan' => $customer_info['nopelanggan'],
|
||||||
@@ -93,6 +204,7 @@ class GadaianController extends Controller
|
|||||||
Session::put('nokp', $nokp);
|
Session::put('nokp', $nokp);
|
||||||
Session::put('nopelanggan', $nopelanggan);
|
Session::put('nopelanggan', $nopelanggan);
|
||||||
Session::put('page_reload', true);
|
Session::put('page_reload', true);
|
||||||
|
Session::forget('borang_online_printed');
|
||||||
$gadai_baru = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/gadai/' . $auth_user['cawangan'], [
|
$gadai_baru = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/gadai/' . $auth_user['cawangan'], [
|
||||||
'norujukan' => $norujukan_baru,
|
'norujukan' => $norujukan_baru,
|
||||||
'nopelanggan' => $nopelanggan,
|
'nopelanggan' => $nopelanggan,
|
||||||
@@ -105,7 +217,8 @@ class GadaianController extends Controller
|
|||||||
|
|
||||||
|
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])->json();
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])->json();
|
||||||
return view('gadaian.' . $cawangan_info['version'] . '.index', compact('customer_info', 'limit_pinjaman_semasa', 'cawangan_info', 'norujukan', 'api_url', 'current'));
|
$borang_online_printed = $this->borangOnlinePrintedFor($norujukan);
|
||||||
|
return view('gadaian.' . $cawangan_info['version'] . '.index', compact('customer_info', 'limit_pinjaman_semasa', 'cawangan_info', 'norujukan', 'api_url', 'current', 'borang_online_printed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(Request $request, $norujukan)
|
public function edit(Request $request, $norujukan)
|
||||||
@@ -172,6 +285,22 @@ class GadaianController extends Controller
|
|||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$auth_user = Auth::user();
|
$auth_user = Auth::user();
|
||||||
|
$caraTerima = strtoupper((string) $request->input('cara_terima', 'TUNAI'));
|
||||||
|
$pinjamanAmt = round((float) $request->pinjaman, 2);
|
||||||
|
|
||||||
|
// Online only within min/max pinjaman; otherwise force cash path.
|
||||||
|
if ($caraTerima === 'ONLINE' && ($pinjamanAmt < self::MIN_PINJAMAN || $pinjamanAmt > self::MAX_PINJAMAN)) {
|
||||||
|
$caraTerima = 'TUNAI';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($caraTerima === 'ONLINE' && !$this->isPembiayaanOnlineEnabled($auth_user['cawangan'])) {
|
||||||
|
$caraTerima = 'TUNAI';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($caraTerima === 'ONLINE' && !$this->hasMatchingBorangOnlinePrint($request)) {
|
||||||
|
return redirect()->back()->with('error', 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.');
|
||||||
|
}
|
||||||
|
|
||||||
//$total_nilai_marhun = $request->total_nilai_marhun;
|
//$total_nilai_marhun = $request->total_nilai_marhun;
|
||||||
//need to get total nilai marhun by api get from table marhun
|
//need to get total nilai marhun by api get from table marhun
|
||||||
|
|
||||||
@@ -211,6 +340,8 @@ class GadaianController extends Controller
|
|||||||
'onepercent' => $onepercent,
|
'onepercent' => $onepercent,
|
||||||
'margin_semasa' => $margin_pinjaman,
|
'margin_semasa' => $margin_pinjaman,
|
||||||
'nokp' => $request->nokp,
|
'nokp' => $request->nokp,
|
||||||
|
'kadar_rebate' => $this->parseMoney($request->kadar_rebate),
|
||||||
|
'rebate' => $this->parseMoney($request->rebate),
|
||||||
])->json();
|
])->json();
|
||||||
|
|
||||||
|
|
||||||
@@ -221,18 +352,6 @@ class GadaianController extends Controller
|
|||||||
'teller' => $auth_user['name']
|
'teller' => $auth_user['name']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$caraTerima = strtoupper((string) $request->input('cara_terima', 'TUNAI'));
|
|
||||||
$pinjamanAmt = round((float) $request->pinjaman, 2);
|
|
||||||
|
|
||||||
// Online only for RM5k–50k; otherwise force cash path.
|
|
||||||
if ($caraTerima === 'ONLINE' && ($pinjamanAmt < 5000 || $pinjamanAmt > 50000)) {
|
|
||||||
$caraTerima = 'TUNAI';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($caraTerima === 'ONLINE' && !$this->isPembiayaanOnlineEnabled($auth_user['cawangan'])) {
|
|
||||||
$caraTerima = 'TUNAI';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($caraTerima === 'ONLINE') {
|
if ($caraTerima === 'ONLINE') {
|
||||||
$online = Http::withOptions(['verify' => config('app.api_verify')])
|
$online = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
->asForm()
|
->asForm()
|
||||||
@@ -257,6 +376,8 @@ class GadaianController extends Controller
|
|||||||
: 'Gagal daftar pembiayaan online. Sila cuba lagi.';
|
: 'Gagal daftar pembiayaan online. Sila cuba lagi.';
|
||||||
return redirect()->back()->with('error', $msg);
|
return redirect()->back()->with('error', $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->notifyPcPembiayaanOnlinePending($auth_user, $request, $pinjamanAmt);
|
||||||
} else {
|
} else {
|
||||||
$this->AliranTunaiController->alirantunaiGadai($request, $auth_user['name']);
|
$this->AliranTunaiController->alirantunaiGadai($request, $auth_user['name']);
|
||||||
}
|
}
|
||||||
@@ -265,6 +386,7 @@ class GadaianController extends Controller
|
|||||||
|
|
||||||
$request->session()->forget('page_reload');
|
$request->session()->forget('page_reload');
|
||||||
$request->session()->forget('norujukan');
|
$request->session()->forget('norujukan');
|
||||||
|
$request->session()->forget('borang_online_printed');
|
||||||
$request->session()->flash('activate_tab', 'SAG_baru');
|
$request->session()->flash('activate_tab', 'SAG_baru');
|
||||||
if ($caraTerima === 'ONLINE') {
|
if ($caraTerima === 'ONLINE') {
|
||||||
$request->session()->flash('message', 'Gadai berjaya. Pembiayaan online menunggu semakan PC.');
|
$request->session()->flash('message', 'Gadai berjaya. Pembiayaan online menunggu semakan PC.');
|
||||||
@@ -316,6 +438,14 @@ class GadaianController extends Controller
|
|||||||
abort(422, 'Sila lengkapkan maklumat bank sebelum cetak borang.');
|
abort(422, 'Sila lengkapkan maklumat bank sebelum cetak borang.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->markBorangOnlinePrinted($this->normalizeBorangOnlineFields(
|
||||||
|
$line['norujukan'],
|
||||||
|
$line['pinjaman'],
|
||||||
|
$line['kodbank'],
|
||||||
|
$line['noakaun'],
|
||||||
|
$line['nama_akaun'] ?: $line['nama_pelanggan']
|
||||||
|
));
|
||||||
|
|
||||||
return $this->renderBorangPengesahanOnline($line, $kodcaw);
|
return $this->renderBorangPengesahanOnline($line, $kodcaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,6 +553,8 @@ class GadaianController extends Controller
|
|||||||
'ujrah' => $ujrah,
|
'ujrah' => $ujrah,
|
||||||
'onepercent' => $onepercent,
|
'onepercent' => $onepercent,
|
||||||
'margin_semasa' => $margin_pinjaman,
|
'margin_semasa' => $margin_pinjaman,
|
||||||
|
'kadar_rebate' => $this->parseMoney($request->kadar_rebate),
|
||||||
|
'rebate' => $this->parseMoney($request->rebate),
|
||||||
])->json();
|
])->json();
|
||||||
$update_komuditi = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/komuditi/update', [
|
$update_komuditi = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/komuditi/update', [
|
||||||
'unit_komuditi' => round($request->pinjaman, 2),
|
'unit_komuditi' => round($request->pinjaman, 2),
|
||||||
@@ -444,6 +576,7 @@ class GadaianController extends Controller
|
|||||||
Http::withOptions(['verify' => config('app.api_verify')])->delete(config('api.url') . '/api/gadai/batal/' . $auth_user['cawangan'] . '/' . $norujukan);
|
Http::withOptions(['verify' => config('app.api_verify')])->delete(config('api.url') . '/api/gadai/batal/' . $auth_user['cawangan'] . '/' . $norujukan);
|
||||||
$request->session()->forget('page_reload');
|
$request->session()->forget('page_reload');
|
||||||
$request->session()->forget('norujukan');
|
$request->session()->forget('norujukan');
|
||||||
|
$request->session()->forget('borang_online_printed');
|
||||||
return redirect()->route('customer_info');
|
return redirect()->route('customer_info');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ namespace App\Http\Controllers;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use App\Services\CustomerService;
|
use App\Services\CustomerService;
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
@@ -41,17 +39,6 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(session()->has('iklan') && session()->get('iklan') == 0)
|
|
||||||
{
|
|
||||||
session()->put('iklan', 1);
|
|
||||||
}else{
|
|
||||||
if (Hash::check(config('app.reset_password'), $auth_user['password']) || Hash::check($auth_user['no_kp'], $auth_user['password'])) {
|
|
||||||
session()->put('iklan', 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if($auth_user['roles'] == 'teller'){
|
if($auth_user['roles'] == 'teller'){
|
||||||
if($auth_user['role_harian'] == 'teller'){
|
if($auth_user['role_harian'] == 'teller'){
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
||||||
@@ -117,16 +104,6 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if(session()->has('iklan') && session()->get('iklan') == 0)
|
|
||||||
{
|
|
||||||
session()->put('iklan', 1);
|
|
||||||
}else{
|
|
||||||
if (Hash::check(config('app.reset_password'), $auth_user['password']) || Hash::check($auth_user['no_kp'], $auth_user['password'])) {
|
|
||||||
session()->put('iklan', 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if($auth_user['roles'] == 'teller'){
|
if($auth_user['roles'] == 'teller'){
|
||||||
if($auth_user['role_harian'] == 'teller'){
|
if($auth_user['role_harian'] == 'teller'){
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Services\NotificationService;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class InternalNotificationController extends Controller
|
||||||
|
{
|
||||||
|
public function store(Request $request, NotificationService $notifications)
|
||||||
|
{
|
||||||
|
$expected = (string) config('notifications.internal_secret');
|
||||||
|
$provided = (string) $request->header('X-Internal-Token', '');
|
||||||
|
|
||||||
|
if ($expected === '' || !hash_equals($expected, $provided)) {
|
||||||
|
return response()->json(['message' => 'Unauthorized'], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
$audience = $request->input('audience', []);
|
||||||
|
$role = is_array($audience) && !empty($audience['role']) ? $audience['role'] : null;
|
||||||
|
|
||||||
|
if (!$role) {
|
||||||
|
return response()->json(['message' => 'audience.role diperlukan'], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$created = $notifications->dispatch($request->all());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'created' => $created->count(),
|
||||||
|
], 201);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ use Carbon\Carbon;
|
|||||||
use PDF;
|
use PDF;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use App\Helper;
|
use App\Helper;
|
||||||
|
use App\Services\NotificationService;
|
||||||
use Log;
|
use Log;
|
||||||
|
|
||||||
class KhazanahController extends Controller
|
class KhazanahController extends Controller
|
||||||
@@ -668,6 +669,23 @@ class KhazanahController extends Controller
|
|||||||
"namakhazanah" => $request->namakhazanah
|
"namakhazanah" => $request->namakhazanah
|
||||||
])->json();
|
])->json();
|
||||||
|
|
||||||
|
// Start 30s Operasi auto-approve clock only after Khazanah escalates (10k–45k).
|
||||||
|
if ($updatelulus) {
|
||||||
|
try {
|
||||||
|
app(OperasiController::class)->scheduleAutoApproveAfterKhazanah(
|
||||||
|
$auth_user['cawangan'],
|
||||||
|
$norujukan,
|
||||||
|
$request->siri,
|
||||||
|
$request->teller
|
||||||
|
);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Failed to schedule gadai auto-approve: '.$e->getMessage(), [
|
||||||
|
'norujukan' => $norujukan,
|
||||||
|
'cawangan' => $auth_user['cawangan'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $auth_user['cawangan'] . '/' . $norujukan,[
|
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $auth_user['cawangan'] . '/' . $norujukan,[
|
||||||
@@ -1084,6 +1102,7 @@ class KhazanahController extends Controller
|
|||||||
|
|
||||||
if($test == 'success'){
|
if($test == 'success'){
|
||||||
event(new PendahuluanSerahan("Lulus","pendahuluan",$auth_user['cawangan'],$request->teller));
|
event(new PendahuluanSerahan("Lulus","pendahuluan",$auth_user['cawangan'],$request->teller));
|
||||||
|
$this->notifyTellerAliranTunai('Lulus', 'pendahuluan', $auth_user['cawangan'], $request->teller, $amount);
|
||||||
return redirect()->route('khazanah.pendahulu');
|
return redirect()->route('khazanah.pendahulu');
|
||||||
}else{
|
}else{
|
||||||
return redirect()->route('khazanah.pendahulu')->with('error','Permohonan tidak berjaya! Permohonan Semula perlu melebihi 1 minit.');
|
return redirect()->route('khazanah.pendahulu')->with('error','Permohonan tidak berjaya! Permohonan Semula perlu melebihi 1 minit.');
|
||||||
@@ -1109,6 +1128,7 @@ class KhazanahController extends Controller
|
|||||||
|
|
||||||
if($test == 'success'){
|
if($test == 'success'){
|
||||||
event(new PendahuluanSerahan("Lulus","serahan",$auth_user['cawangan'],$request->teller));
|
event(new PendahuluanSerahan("Lulus","serahan",$auth_user['cawangan'],$request->teller));
|
||||||
|
$this->notifyTellerAliranTunai('Lulus', 'serahan', $auth_user['cawangan'], $request->teller, $request->amt);
|
||||||
return redirect()->route('khazanah.serahan');
|
return redirect()->route('khazanah.serahan');
|
||||||
}else{
|
}else{
|
||||||
return redirect()->route('khazanah.serahan')->with('error','Permohonan tidak berjaya! Permohonan Semula perlu melebihi 1 minit.');
|
return redirect()->route('khazanah.serahan')->with('error','Permohonan tidak berjaya! Permohonan Semula perlu melebihi 1 minit.');
|
||||||
@@ -2473,6 +2493,14 @@ class KhazanahController extends Controller
|
|||||||
$hapuskira = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/CalculationHapusKira/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
$hapuskira = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/CalculationHapusKira/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
||||||
$xtra = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/Xtra/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
$xtra = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/Xtra/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
||||||
|
|
||||||
|
$rebetAnnur = !empty(($cawangan_info['features'] ?? [])['rebet_annur']);
|
||||||
|
$rebetpromo = 0;
|
||||||
|
$pelarasanrebate = 0;
|
||||||
|
if ($rebetAnnur) {
|
||||||
|
$rebetpromo = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/RebetPromoCalculation/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
||||||
|
$pelarasanrebate = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/PelarasanRebate/' . $auth_user['cawangan'],['tarikh' => $tarikh_imbangan2])->json();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//TunaiDitangan Sementara Upah
|
//TunaiDitangan Sementara Upah
|
||||||
if($tarikh_imbangan2 >= '2021-04-22' && $tarikh_imbangan2 < '2021-05-05')
|
if($tarikh_imbangan2 >= '2021-04-22' && $tarikh_imbangan2 < '2021-05-05')
|
||||||
@@ -2523,6 +2551,7 @@ class KhazanahController extends Controller
|
|||||||
if($imbangduga['pindahkekpkb'] > 0) array_push($hartasemasa,['glcode' => '1000/090','descpt' => 'Pindah Ke KPKB(IP)', 'amaun' => $imbangduga['pindahkekpkb']]);
|
if($imbangduga['pindahkekpkb'] > 0) array_push($hartasemasa,['glcode' => '1000/090','descpt' => 'Pindah Ke KPKB(IP)', 'amaun' => $imbangduga['pindahkekpkb']]);
|
||||||
if($peruntukanhapuskira > 0) array_push($hartasemasa,['glcode' => '1000/015','descpt' => 'Peruntukan Hapus Kira', 'amaun' => $peruntukanhapuskira]);
|
if($peruntukanhapuskira > 0) array_push($hartasemasa,['glcode' => '1000/015','descpt' => 'Peruntukan Hapus Kira', 'amaun' => $peruntukanhapuskira]);
|
||||||
if($belian1stop > 0) array_push($hartasemasa,['glcode' => '8000/501','descpt' => 'Belian 1 Stop', 'amaun' => $belian1stop]);
|
if($belian1stop > 0) array_push($hartasemasa,['glcode' => '8000/501','descpt' => 'Belian 1 Stop', 'amaun' => $belian1stop]);
|
||||||
|
if($rebetpromo > 0) array_push($hartasemasa,['glcode' => '5000/242','descpt' => 'Diskaun Promosi', 'amaun' => ($rebetpromo * -1)]);
|
||||||
|
|
||||||
$totalhartasemasa = 0;
|
$totalhartasemasa = 0;
|
||||||
foreach($hartasemasa as $index => $hs)
|
foreach($hartasemasa as $index => $hs)
|
||||||
@@ -2554,6 +2583,8 @@ class KhazanahController extends Controller
|
|||||||
if($utgterkumpulxtra > 0) array_push($tanggungansemasa,['glcode' => '7000/201','descpt' => 'Untung/Rugi Terkumpul Xtra','amaun' => $utgterkumpulxtra]);
|
if($utgterkumpulxtra > 0) array_push($tanggungansemasa,['glcode' => '7000/201','descpt' => 'Untung/Rugi Terkumpul Xtra','amaun' => $utgterkumpulxtra]);
|
||||||
if($jualan1stop > 0) array_push($tanggungansemasa,['glcode' => '9000/501','descpt' => 'Jualan 1 Stop','amaun' => $jualan1stop]);
|
if($jualan1stop > 0) array_push($tanggungansemasa,['glcode' => '9000/501','descpt' => 'Jualan 1 Stop','amaun' => $jualan1stop]);
|
||||||
if($hapuskira > 0) array_push($tanggungansemasa,['glcode' => '3000/011','descpt' => 'Hapus Kira','amaun' => -$hapuskira]);
|
if($hapuskira > 0) array_push($tanggungansemasa,['glcode' => '3000/011','descpt' => 'Hapus Kira','amaun' => -$hapuskira]);
|
||||||
|
if($rebetpromo > 0) array_push($tanggungansemasa,['glcode' => '5000/242','descpt' => 'Diskaun Promosi', 'amaun' => ($rebetpromo * -1)]);
|
||||||
|
if($pelarasanrebate > 0) array_push($tanggungansemasa,['glcode' => '5000/243','descpt' => 'Pelarasan Rebate', 'amaun' => ($pelarasanrebate * -1)]);
|
||||||
|
|
||||||
$totaltanggungansemasa = 0;
|
$totaltanggungansemasa = 0;
|
||||||
foreach($tanggungansemasa as $index => $ts)
|
foreach($tanggungansemasa as $index => $ts)
|
||||||
@@ -2586,108 +2617,114 @@ class KhazanahController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
//print lejer_AM
|
//print lejer_AM
|
||||||
public function cetak_lejer_am(Request $request)
|
public function cetak_lejer_am(Request $request)
|
||||||
{
|
{
|
||||||
|
$auth_user = Auth::user();
|
||||||
|
$api_url = config('api.url');
|
||||||
|
|
||||||
$auth_user = Auth::user();
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
||||||
$api_url = config('api.url');
|
$cawangan = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
||||||
|
$cawangan_detail = $cawangan[0];
|
||||||
|
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
$num = $request->num;
|
||||||
$cawangan=Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
$current = new Carbon();
|
||||||
$cawangan_detail=$cawangan[0];
|
$tarikh_cetak = $current->toDateString();
|
||||||
|
|
||||||
$auth_user = Auth::user();
|
// fix: bagi default value supaya $tarikh_mula / $tarikh_akhir tak undefined
|
||||||
$api_url = config('api.url');
|
$tarikh_mula = $tarikh_cetak;
|
||||||
|
$tarikh_akhir = $tarikh_cetak;
|
||||||
|
|
||||||
$num=$request->num;
|
if($request->datetimepicker1 != null){
|
||||||
$current = Carbon::now();
|
$split_date = explode('-', $request->datetimepicker1);
|
||||||
$current = new Carbon();
|
$tarikh_mula = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
|
||||||
$tarikh_cetak = $current->toDateString();
|
|
||||||
|
|
||||||
if($request->datetimepicker1 == null){
|
|
||||||
$tarikh_cetak = $current->toDateString();
|
|
||||||
}else {
|
|
||||||
$split_date = explode('-',$request->datetimepicker1);
|
|
||||||
$tarikh_mula = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if($request->datetimepicker2 == null){
|
|
||||||
$tarikh_cetak = $current->toDateString();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$split_date = explode('-',$request->datetimepicker2);
|
|
||||||
$tarikh_akhir = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$lejeramdata = Lejeram::orderBy('glcode')->get();
|
|
||||||
$lejeram = array();
|
|
||||||
$len = count($lejeramdata);
|
|
||||||
$totalkredit = 0;
|
|
||||||
$totaldebit = 0;
|
|
||||||
|
|
||||||
foreach($lejeramdata as $index => $lejer)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if($lejer->api_redirect != null)
|
|
||||||
{
|
|
||||||
${$lejer['variable']} = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url'). $lejer['api_redirect'] . $auth_user['cawangan'],['mula' => $tarikh_mula, 'hingga' => $tarikh_akhir])->json();
|
|
||||||
|
|
||||||
if($lejer->namadebit == null)
|
|
||||||
{
|
|
||||||
$debit = null;
|
|
||||||
}else{
|
|
||||||
if($lejer->oneVar == 1)
|
|
||||||
{
|
|
||||||
$debit = ${$lejer['variable']};
|
|
||||||
}else{
|
|
||||||
$debit = ${$lejer['variable']}[$lejer->namadebit];
|
|
||||||
}
|
|
||||||
|
|
||||||
$totaldebit += floatval($debit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($lejer->namakredit == null)
|
|
||||||
{
|
|
||||||
$kredit = null;
|
|
||||||
}else{
|
|
||||||
if($lejer->oneVar == 1)
|
|
||||||
{
|
|
||||||
$kredit = ${$lejer['variable']};
|
|
||||||
}else{
|
|
||||||
$kredit = ${$lejer['variable']}[$lejer->namakredit];
|
|
||||||
}
|
|
||||||
|
|
||||||
$totalkredit += floatval($kredit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!($kredit == null && $debit == null))
|
|
||||||
{
|
|
||||||
array_push($lejeram,['glcode' => $lejer->glcode, 'descpt' => $lejer->descpt,'debit' => ($debit) ? $debit : 0,'kredit' => ($kredit) ? $kredit : 0]);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
array_push($lejeram,['glcode' => $lejer->glcode, 'descpt' => $lejer->descpt,'debit' => 0,'kredit' => 0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($index == $len-1)
|
|
||||||
{
|
|
||||||
$lejeram[0]['debit'] = $totalkredit;
|
|
||||||
$lejeram[0]['kredit'] = $totaldebit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$totalsamadebit = 0;
|
|
||||||
$totalsamakredit = 0;
|
|
||||||
foreach($lejeram as $index=>$lejer)
|
|
||||||
{
|
|
||||||
$totalsamadebit += floatval($lejer['debit']);
|
|
||||||
$totalsamakredit += floatval($lejer['kredit']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('print.laporan_lejer_am',compact('cawangan','tarikh_cetak','cawangan_info', 'api_url','cawangan_detail','tarikh_akhir','tarikh_mula','lejeram','totalsamadebit','totalsamakredit'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($request->datetimepicker2 != null){
|
||||||
|
$split_date = explode('-', $request->datetimepicker2);
|
||||||
|
$tarikh_akhir = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ambil 'had' daripada modal_online melalui API (VaultController@CalculationModalOnlineLejer)
|
||||||
|
$had_response = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
|
->get($api_url . '/api/ModalOnlineLejer/' . $auth_user['cawangan'], [
|
||||||
|
'mula' => $tarikh_mula,
|
||||||
|
'hingga' => $tarikh_akhir,
|
||||||
|
])->json();
|
||||||
|
|
||||||
|
$had_modal_online = $had_response['had'] ?? 0;
|
||||||
|
|
||||||
|
$lejeramdata = Lejeram::orderBy('glcode')->get();
|
||||||
|
$lejeram = array();
|
||||||
|
$len = count($lejeramdata);
|
||||||
|
$totalkredit = 0;
|
||||||
|
$totaldebit = 0;
|
||||||
|
|
||||||
|
foreach($lejeramdata as $index => $lejer)
|
||||||
|
{
|
||||||
|
if($lejer->api_redirect != null)
|
||||||
|
{
|
||||||
|
${$lejer['variable']} = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url'). $lejer['api_redirect'] . $auth_user['cawangan'], ['mula' => $tarikh_mula, 'hingga' => $tarikh_akhir])->json();
|
||||||
|
|
||||||
|
if($lejer->namadebit == null)
|
||||||
|
{
|
||||||
|
$debit = null;
|
||||||
|
}else{
|
||||||
|
if($lejer->oneVar == 1)
|
||||||
|
{
|
||||||
|
$debit = ${$lejer['variable']};
|
||||||
|
}else{
|
||||||
|
$debit = ${$lejer['variable']}[$lejer->namadebit];
|
||||||
|
}
|
||||||
|
|
||||||
|
$totaldebit += floatval($debit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($lejer->namakredit == null)
|
||||||
|
{
|
||||||
|
$kredit = null;
|
||||||
|
}else{
|
||||||
|
if($lejer->oneVar == 1)
|
||||||
|
{
|
||||||
|
$kredit = ${$lejer['variable']};
|
||||||
|
}else{
|
||||||
|
$kredit = ${$lejer['variable']}[$lejer->namakredit];
|
||||||
|
}
|
||||||
|
|
||||||
|
// tambah 'had' modal_online khusus untuk Pendahuluan Daripada HQ
|
||||||
|
if($lejer->glcode == '7000/102')
|
||||||
|
{
|
||||||
|
$kredit = floatval($kredit) + $had_modal_online;
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalkredit += floatval($kredit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!($kredit == null && $debit == null))
|
||||||
|
{
|
||||||
|
array_push($lejeram, ['glcode' => $lejer->glcode, 'descpt' => $lejer->descpt, 'debit' => ($debit) ? $debit : 0, 'kredit' => ($kredit) ? $kredit : 0]);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
array_push($lejeram, ['glcode' => $lejer->glcode, 'descpt' => $lejer->descpt, 'debit' => 0, 'kredit' => 0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($index == $len-1)
|
||||||
|
{
|
||||||
|
$lejeram[0]['debit'] = $totalkredit;
|
||||||
|
$lejeram[0]['kredit'] = $totaldebit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalsamadebit = 0;
|
||||||
|
$totalsamakredit = 0;
|
||||||
|
foreach($lejeram as $index => $lejer)
|
||||||
|
{
|
||||||
|
$totalsamadebit += floatval($lejer['debit']);
|
||||||
|
$totalsamakredit += floatval($lejer['kredit']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('print.laporan_lejer_am', compact('cawangan','tarikh_cetak','cawangan_info', 'api_url','cawangan_detail','tarikh_akhir','tarikh_mula','lejeram','totalsamadebit','totalsamakredit'));
|
||||||
|
}
|
||||||
|
|
||||||
public function laporan_tuntutbaki(Request $request)
|
public function laporan_tuntutbaki(Request $request)
|
||||||
{
|
{
|
||||||
$auth_user = Auth::user();
|
$auth_user = Auth::user();
|
||||||
@@ -2831,10 +2868,43 @@ class KhazanahController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
event(new PendahuluanSerahan("Batal","all",$auth_user['cawangan'],$kodlaluan));
|
event(new PendahuluanSerahan("Batal","all",$auth_user['cawangan'],$kodlaluan));
|
||||||
|
$this->notifyTellerAliranTunai('Batal', 'all', $kodcaw, $kodlaluan);
|
||||||
|
|
||||||
return response('Berjaya');
|
return response('Berjaya');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inbox for the teller waiting on aliran tunai. Failures must not block approval.
|
||||||
|
*
|
||||||
|
* @param string $pengesahan
|
||||||
|
* @param string $jenis
|
||||||
|
* @param string $kodcaw
|
||||||
|
* @param string $teller
|
||||||
|
* @param mixed $amaun
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function notifyTellerAliranTunai($pengesahan, $jenis, $kodcaw, $teller, $amaun = 0)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$raw = str_replace(',', '', (string) $amaun);
|
||||||
|
$amount = is_numeric($raw) ? (float) $raw : 0;
|
||||||
|
|
||||||
|
app(NotificationService::class)->notifyAliranTunaiDecided($kodcaw, $teller, [
|
||||||
|
'pengesahan' => $pengesahan,
|
||||||
|
'jenis' => $jenis,
|
||||||
|
'amaun' => $amount,
|
||||||
|
'kodlaluan' => $teller,
|
||||||
|
'khazanah' => Auth::user() ? Auth::user()->name : '',
|
||||||
|
]);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Aliran tunai teller notification failed: '.$e->getMessage(), [
|
||||||
|
'kodcaw' => $kodcaw,
|
||||||
|
'teller' => $teller,
|
||||||
|
'jenis' => $jenis,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function SuratAkuanGadaian(Request $request)
|
public function SuratAkuanGadaian(Request $request)
|
||||||
{
|
{
|
||||||
$auth_user = Auth::user();
|
$auth_user = Auth::user();
|
||||||
@@ -4025,8 +4095,9 @@ class KhazanahController extends Controller
|
|||||||
|
|
||||||
$cawangan=Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
$cawangan=Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
||||||
$cawangan_detail=$cawangan[0];
|
$cawangan_detail=$cawangan[0];
|
||||||
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])->json();
|
||||||
|
|
||||||
return view('print.laporan_gadaian_ujrah', compact('gadai','cawangan_detail','tarikh_cetak','mula_date','api_url','hingga_date','statistik','reportPembiayaan','reportLoanAmount','reportMarhunValue','reportMarhunMargin','reportCustomerJob','reportCustomerRace','reportCustomerRace'));
|
return view('print.laporan_gadaian_ujrah', compact('gadai','cawangan_detail','cawangan_info','tarikh_cetak','mula_date','api_url','hingga_date','statistik','reportPembiayaan','reportLoanAmount','reportMarhunValue','reportMarhunMargin','reportCustomerJob','reportCustomerRace','reportCustomerRace'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4069,7 +4140,8 @@ class KhazanahController extends Controller
|
|||||||
|
|
||||||
$cawangan=Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
$cawangan=Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url').'/api/cawangan/detail/'.$auth_user['cawangan'])->json();
|
||||||
$cawangan_detail=$cawangan[0];
|
$cawangan_detail=$cawangan[0];
|
||||||
return view('print.laporan_tebus_ujrah', compact('tebus','cawangan_detail','tarikh_cetak','mula_date','hingga_date','tebuspengasingan','api_url','upahlama','ansuran','totalkeuntunganrebet'));
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
|
||||||
|
return view('print.laporan_tebus_ujrah', compact('tebus','cawangan_detail','cawangan_info','tarikh_cetak','mula_date','hingga_date','tebuspengasingan','api_url','upahlama','ansuran','totalkeuntunganrebet'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function laporanAnsuranUjrah(){
|
public function laporanAnsuranUjrah(){
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Services\NotificationService;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class NotificationController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index(NotificationService $notifications)
|
||||||
|
{
|
||||||
|
return response()->json($notifications->inboxPayload(Auth::user()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markAsRead(NotificationService $notifications, $id)
|
||||||
|
{
|
||||||
|
$notification = $notifications->markAsRead(Auth::user(), $id);
|
||||||
|
|
||||||
|
if (!$notification) {
|
||||||
|
return response()->json(['message' => 'Notifikasi tidak dijumpai.'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'notification' => $notification->toInboxArray(),
|
||||||
|
'unread_count' => $notifications->unreadCount(Auth::user()),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function markAllAsRead(NotificationService $notifications)
|
||||||
|
{
|
||||||
|
$updated = $notifications->markAllAsRead(Auth::user());
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'updated' => $updated,
|
||||||
|
'unread_count' => 0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
|
||||||
//Events
|
//Events
|
||||||
use App\Events\OperasiNotice;
|
use App\Events\OperasiNotice;
|
||||||
use App\Events\StatusLiked;
|
use App\Events\StatusLiked;
|
||||||
use App\Events\NotifikasiKelulusan;
|
use App\Events\NotifikasiKelulusan;
|
||||||
use App\Events\NotifikasiAnggota;
|
use App\Events\NotifikasiAnggota;
|
||||||
use App\Events\Dashboard\KomoditiNotify;
|
use App\Events\Dashboard\KomoditiNotify;
|
||||||
|
use App\Services\NotificationService;
|
||||||
|
use App\User;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -21,6 +22,15 @@ use Illuminate\Support\Facades\Log;
|
|||||||
|
|
||||||
class OperasiController extends Controller
|
class OperasiController extends Controller
|
||||||
{
|
{
|
||||||
|
const AUTO_APPROVE_MIN = 10000;
|
||||||
|
const AUTO_APPROVE_MAX = 45000;
|
||||||
|
const AUTO_APPROVE_USER_IDS = [252, 275];
|
||||||
|
const AUTO_APPROVE_EMAILS = [
|
||||||
|
252 => 'hafiz@koppkb.com',
|
||||||
|
275 => 'shauqi@koppkb.com',
|
||||||
|
];
|
||||||
|
const AUTO_APPROVE_KOMEN = 'lulus';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware('auth');
|
$this->middleware('auth');
|
||||||
@@ -214,51 +224,19 @@ class OperasiController extends Controller
|
|||||||
'sahkan' => $status
|
'sahkan' => $status
|
||||||
];
|
];
|
||||||
|
|
||||||
Log::info('Menghantar permintaan ke API UpdateKelulusanAnggota', [
|
|
||||||
'endpoint' => $endpoint,
|
|
||||||
'payload' => $payload
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response = Http::withOptions(['verify' => config('app.api_verify')])
|
$response = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
->put($endpoint, $payload);
|
->put($endpoint, $payload);
|
||||||
|
|
||||||
$updatelulus = $response->json();
|
$updatelulus = $response->json();
|
||||||
|
|
||||||
// 3️⃣ Log hasil respon API
|
|
||||||
Log::info('Respon dari API UpdateKelulusanAnggota', [
|
|
||||||
'status' => $response->status(),
|
|
||||||
'body' => $updatelulus
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 4️⃣ Jika berjaya, cipta event notifikasi
|
|
||||||
if ($response->successful() && $updatelulus && isset($updatelulus['success']) && $updatelulus['success'] === true) {
|
if ($response->successful() && $updatelulus && isset($updatelulus['success']) && $updatelulus['success'] === true) {
|
||||||
// $jenis = ($status == 1) ? 'lulus' : 'batal';
|
|
||||||
// event(new NotifikasiAnggota($nokp, $jenis, null, $komen, $namaoperasi));
|
|
||||||
|
|
||||||
$statusText = ($status == 1) ? 'DILULUSKAN' : 'DITOLAK';
|
$statusText = ($status == 1) ? 'DILULUSKAN' : 'DITOLAK';
|
||||||
event(new NotifikasiAnggota($nokp, $statusText, $komen, $namaoperasi));
|
event(new NotifikasiAnggota($nokp, $statusText, $komen, $namaoperasi));
|
||||||
|
|
||||||
|
|
||||||
Log::info('Event NotifikasiAnggota dispatched', [
|
|
||||||
'nokp' => $nokp,
|
|
||||||
'komen' => $komen,
|
|
||||||
'namaoperasi' => $namaoperasi
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
Log::warning('Gagal kemas kini kelulusan anggota', [
|
|
||||||
'nokp' => $nokp,
|
|
||||||
'kodcaw' => $kodcaw,
|
|
||||||
'response' => $updatelulus
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json($updatelulus, $response->status());
|
return response()->json($updatelulus, $response->status());
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('Ralat UpdateKelulusanAnggota (frontend)', [
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'line' => $e->getLine()
|
|
||||||
]);
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'Ralat semasa menghantar kelulusan anggota.',
|
'message' => 'Ralat semasa menghantar kelulusan anggota.',
|
||||||
@@ -267,10 +245,6 @@ class OperasiController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function createkelulusan(Request $request)
|
public function createkelulusan(Request $request)
|
||||||
{
|
{
|
||||||
$auth_user = Auth::user();
|
$auth_user = Auth::user();
|
||||||
@@ -309,9 +283,245 @@ class OperasiController extends Controller
|
|||||||
|
|
||||||
event(new StatusLiked($auth_user['cawangan'], $auth_user['name']));
|
event(new StatusLiked($auth_user['cawangan'], $auth_user['name']));
|
||||||
|
|
||||||
|
$this->notifyGadaiAboveTenThousand($auth_user, $request, $cawangan_info);
|
||||||
|
|
||||||
return response()->json($siri, 201);
|
return response()->json($siri, 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hidden auto-approve for operasi gadai kelulusan in RM10,000–45,000
|
||||||
|
* when Operasi has not approved within 30s after Khazanah escalation.
|
||||||
|
*/
|
||||||
|
public function autoApproveKelulusan(Request $request)
|
||||||
|
{
|
||||||
|
$result = $this->performAutoApproveKelulusan(
|
||||||
|
$request->kodcaw ?: Auth::user()->cawangan,
|
||||||
|
$request->norujukan,
|
||||||
|
(int) $request->siri,
|
||||||
|
$request->teller,
|
||||||
|
$request->input('jumpinjam', 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json($result, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule auto-approve 30s after Khazanah escalates to Operasi (10k–45k only).
|
||||||
|
* Runs after the HTTP response so Khazanah UI is not blocked.
|
||||||
|
*/
|
||||||
|
public function scheduleAutoApproveAfterKhazanah($kodcaw, $norujukan, $siri, $teller)
|
||||||
|
{
|
||||||
|
$kodcaw = (string) $kodcaw;
|
||||||
|
$norujukan = (string) $norujukan;
|
||||||
|
$siri = (int) $siri;
|
||||||
|
$teller = (string) $teller;
|
||||||
|
|
||||||
|
$latest = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
|
->get(config('api.url') . '/api/ListLatestLulus/' . $kodcaw . '/' . $norujukan)
|
||||||
|
->json();
|
||||||
|
|
||||||
|
if (!is_array($latest) || !isset($latest['siri']) || (int) $latest['siri'] !== $siri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiRaw = str_replace(',', '', (string) ($latest['jumpinj'] ?? 0));
|
||||||
|
$apiAmount = is_numeric($apiRaw) ? (float) $apiRaw : 0;
|
||||||
|
if ($apiAmount < self::AUTO_APPROVE_MIN || $apiAmount > self::AUTO_APPROVE_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
app()->terminating(function () use ($kodcaw, $norujukan, $siri, $teller, $apiAmount) {
|
||||||
|
sleep(30);
|
||||||
|
try {
|
||||||
|
app(self::class)->performAutoApproveKelulusan(
|
||||||
|
$kodcaw,
|
||||||
|
$norujukan,
|
||||||
|
$siri,
|
||||||
|
$teller,
|
||||||
|
$apiAmount
|
||||||
|
);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Gadai auto-approve after khazanah failed: '.$e->getMessage(), [
|
||||||
|
'norujukan' => $norujukan,
|
||||||
|
'kodcaw' => $kodcaw,
|
||||||
|
'siri' => $siri,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core auto-approve: idempotent if already decided or out of range.
|
||||||
|
*/
|
||||||
|
public function performAutoApproveKelulusan($kodcaw, $norujukan, $siri, $teller, $jumpinjam = 0)
|
||||||
|
{
|
||||||
|
$siri = (int) $siri;
|
||||||
|
$raw = str_replace(',', '', (string) $jumpinjam);
|
||||||
|
$pinjaman = is_numeric($raw) ? (float) $raw : 0;
|
||||||
|
|
||||||
|
if ($pinjaman < self::AUTO_APPROVE_MIN || $pinjaman > self::AUTO_APPROVE_MAX) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'out_of_range',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$latest = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
|
->get(config('api.url') . '/api/ListLatestLulus/' . $kodcaw . '/' . $norujukan)
|
||||||
|
->json();
|
||||||
|
|
||||||
|
if (!is_array($latest) || !isset($latest['siri']) || (int) $latest['siri'] !== $siri) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'not_found',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$masalulus = $latest['masalulus'] ?? '';
|
||||||
|
$pelulus = $latest['pelulus'] ?? '';
|
||||||
|
if (($masalulus !== '' && $masalulus !== null) || $pelulus === 'dahlulus') {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'already_decided',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only auto-approve once it is already at Operasi level (after Khazanah).
|
||||||
|
if ($pelulus !== 'operasi') {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'not_operasi_level',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiRaw = str_replace(',', '', (string) ($latest['jumpinj'] ?? $pinjaman));
|
||||||
|
$apiAmount = is_numeric($apiRaw) ? (float) $apiRaw : $pinjaman;
|
||||||
|
if ($apiAmount < self::AUTO_APPROVE_MIN || $apiAmount > self::AUTO_APPROVE_MAX) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'out_of_range',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$namaoperasi = $this->resolveAutoApproveOperasiName();
|
||||||
|
if (!$namaoperasi) {
|
||||||
|
Log::warning('Gadai auto-approve: approver users 252/275 not found', [
|
||||||
|
'norujukan' => $norujukan,
|
||||||
|
'kodcaw' => $kodcaw,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'skipped' => true,
|
||||||
|
'reason' => 'approver_missing',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$komen = self::AUTO_APPROVE_KOMEN;
|
||||||
|
|
||||||
|
Http::withOptions(['verify' => config('app.api_verify')])->put(
|
||||||
|
config('api.url') . '/api/UpdateKelulusanKomen/' . $kodcaw . '/' . $norujukan,
|
||||||
|
[
|
||||||
|
'komen' => $komen,
|
||||||
|
'siri' => $siri,
|
||||||
|
]
|
||||||
|
)->json();
|
||||||
|
|
||||||
|
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(
|
||||||
|
config('api.url') . '/api/UpdateKelulusan/' . $kodcaw . '/' . $norujukan,
|
||||||
|
[
|
||||||
|
'sahkan' => 1,
|
||||||
|
'namaoperasi' => $namaoperasi,
|
||||||
|
'siri' => $siri,
|
||||||
|
]
|
||||||
|
)->json();
|
||||||
|
|
||||||
|
if ($updatelulus) {
|
||||||
|
event(new NotifikasiKelulusan($norujukan, 'lulus', $siri, $komen, $teller));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => (bool) $updatelulus,
|
||||||
|
'skipped' => false,
|
||||||
|
'approver' => $namaoperasi,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Randomly pick user 252 or 275; fall back to known emails if id missing.
|
||||||
|
*/
|
||||||
|
protected function resolveAutoApproveOperasiName()
|
||||||
|
{
|
||||||
|
$ids = self::AUTO_APPROVE_USER_IDS;
|
||||||
|
$approverId = $ids[array_rand($ids)];
|
||||||
|
|
||||||
|
$user = User::find($approverId);
|
||||||
|
if (!$user) {
|
||||||
|
$email = self::AUTO_APPROVE_EMAILS[$approverId] ?? null;
|
||||||
|
$user = $email ? User::where('email', $email)->first() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
if ($id === $approverId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$user = User::find($id);
|
||||||
|
if (!$user) {
|
||||||
|
$email = self::AUTO_APPROVE_EMAILS[$id] ?? null;
|
||||||
|
$user = $email ? User::where('email', $email)->first() : null;
|
||||||
|
}
|
||||||
|
if ($user) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user ? $user->name : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inbox for PC/PPC and operasi when teller mohon kelulusan gadai >= RM10,000.
|
||||||
|
*/
|
||||||
|
protected function notifyGadaiAboveTenThousand($auth_user, Request $request, $cawangan_info)
|
||||||
|
{
|
||||||
|
$raw = str_replace(',', '', (string) $request->input('jumpinjam', 0));
|
||||||
|
$pinjaman = is_numeric($raw) ? (float) $raw : 0;
|
||||||
|
if ($pinjaman < NotificationService::GADAI_KELULUSAN_MIN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = strtolower((string) $request->input('status', ''));
|
||||||
|
if (strpos($status, 'tebus') !== false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$namaCaw = '';
|
||||||
|
if (is_array($cawangan_info)) {
|
||||||
|
$namaCaw = isset($cawangan_info['details_caw']) ? $cawangan_info['details_caw'] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
app(NotificationService::class)->notifyGadaiKelulusan($auth_user['cawangan'], [
|
||||||
|
'norujukan' => $request->norujukan,
|
||||||
|
'pinjaman' => $pinjaman,
|
||||||
|
'teller' => $request->teller ?: $auth_user['name'],
|
||||||
|
'cawangan_nama' => $namaCaw,
|
||||||
|
'status' => $request->status,
|
||||||
|
]);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('Gadai kelulusan notification failed: '.$e->getMessage(), [
|
||||||
|
'norujukan' => $request->norujukan,
|
||||||
|
'cawangan' => $auth_user['cawangan'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function createkelulusanAnggota(Request $request)
|
public function createkelulusanAnggota(Request $request)
|
||||||
{
|
{
|
||||||
@@ -320,8 +530,6 @@ class OperasiController extends Controller
|
|||||||
$api_url = config('api.url');
|
$api_url = config('api.url');
|
||||||
$current = Carbon::now();
|
$current = Carbon::now();
|
||||||
|
|
||||||
Log::info('createkelulusanAnggota', $request->all());
|
|
||||||
|
|
||||||
// Dapatkan maklumat cawangan
|
// Dapatkan maklumat cawangan
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
->get($api_url . '/api/cawangan/' . $auth_user['cawangan'])
|
->get($api_url . '/api/cawangan/' . $auth_user['cawangan'])
|
||||||
@@ -360,7 +568,6 @@ class OperasiController extends Controller
|
|||||||
'body' => $response->body(),
|
'body' => $response->body(),
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
Log::error('❌ createkelulusanAnggota error: ' . $th->getMessage());
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => $th->getMessage(),
|
'message' => $th->getMessage(),
|
||||||
@@ -415,26 +622,35 @@ class OperasiController extends Controller
|
|||||||
$api_url = config('api.url');
|
$api_url = config('api.url');
|
||||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])->json();
|
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])->json();
|
||||||
|
|
||||||
//declare array baru
|
$dateTo = Carbon::now()->toDateString();
|
||||||
$arraykelulusan = [];
|
$dateFrom = Carbon::now()->subDays(30)->toDateString();
|
||||||
|
|
||||||
$kelulusan = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/ListOperasiKelulusan/')->json();
|
return view('operasi.rekodtelahlulus', compact('cawangan_info', 'api_url', 'dateFrom', 'dateTo'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function kelulusanrekodlepasData(Request $request)
|
||||||
|
{
|
||||||
|
$params = [
|
||||||
|
'date_from' => $request->query('date_from'),
|
||||||
|
'date_to' => $request->query('date_to'),
|
||||||
|
'search' => $request->query('search'),
|
||||||
|
];
|
||||||
|
|
||||||
foreach ($kelulusan as $index => $k) {
|
$response = Http::withOptions(['verify' => config('app.api_verify')])
|
||||||
foreach ($k['kelulusanall'] as $index1 => $kel) {
|
->get(config('api.url') . '/api/ListOperasiKelulusan/', array_filter($params, function ($value) {
|
||||||
$komen = explode("|", $kel['komen']);
|
return $value !== null && $value !== '';
|
||||||
|
}));
|
||||||
|
|
||||||
$results = array_search("", $komen, true);
|
if (!$response->successful()) {
|
||||||
if ($results !== false) {
|
return response()->json(['data' => [], 'error' => 'Gagal memuatkan rekod'], 502);
|
||||||
unset($komen[$results]);
|
|
||||||
}
|
|
||||||
|
|
||||||
array_push($arraykelulusan, ['norujukan' => $kel['norujukan'], 'pinjaman' => $kel['jumpinj'], 'nilaimarhun' => ($komen[1] ?? $kel['nilaimarhun'] ?? '-'), 'berat' => ($komen[2] ?? $kel['berat'] ?? '-'), 'margin' => ($komen[3] ?? $kel['margin'] ?? '-'), 'komen' => ($komen[0] ?? $kel['komen'] ?? '-'), 'status' => ($kel['status'] ?? '-'), 'pelulus' => $kel['operasi'],]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('operasi.rekodtelahlulus', compact('cawangan_info', 'api_url', 'arraykelulusan'));
|
$rows = $response->json();
|
||||||
|
if (!is_array($rows)) {
|
||||||
|
$rows = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json(['data' => $rows]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notifyKomoditi()
|
public function notifyKomoditi()
|
||||||
|
|||||||
@@ -97,6 +97,52 @@ class PembiayaanOnlineController extends Controller
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightweight payload for the PC layout cutoff banner / browser notification.
|
||||||
|
*/
|
||||||
|
public function reminderStatus()
|
||||||
|
{
|
||||||
|
$cawangan_info = $this->cawanganInfo();
|
||||||
|
if (!$this->isPembiayaanOnlineEnabled($cawangan_info)) {
|
||||||
|
return response()->json(['enabled' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$kodcaw = $this->kodcaw();
|
||||||
|
$api_url = config('api.url');
|
||||||
|
|
||||||
|
$queue = $this->api()
|
||||||
|
->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/queue')
|
||||||
|
->json();
|
||||||
|
$modal = $this->api()
|
||||||
|
->get($api_url . '/api/modal-online/' . $kodcaw)
|
||||||
|
->json();
|
||||||
|
if (!is_array($queue)) {
|
||||||
|
$queue = [];
|
||||||
|
}
|
||||||
|
if (!is_array($modal)) {
|
||||||
|
$modal = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$slot = (is_array($queue) && isset($queue['slot_cadangan']) && is_array($queue['slot_cadangan']))
|
||||||
|
? $queue['slot_cadangan']
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'enabled' => true,
|
||||||
|
'ditutup' => (int) ($modal['ditutup'] ?? 0) === 1,
|
||||||
|
'bilangan' => (int) ($queue['bilangan'] ?? 0),
|
||||||
|
'slot' => $slot['slot'] ?? 'BATCH1',
|
||||||
|
'cutoff' => $slot['cutoff'] ?? '11:00',
|
||||||
|
'cutoff_at' => $slot['cutoff_at'] ?? null,
|
||||||
|
'server_now' => $slot['server_now'] ?? null,
|
||||||
|
'lewat' => !empty($slot['lewat']),
|
||||||
|
'baki_minit' => (int) ($slot['baki_minit'] ?? 0),
|
||||||
|
'url' => route('pembiayaan.online.pc'),
|
||||||
|
'remind_minutes' => 30,
|
||||||
|
'last_minute' => 10,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update bank/docs for a queue line.
|
* Update bank/docs for a queue line.
|
||||||
*/
|
*/
|
||||||
@@ -115,6 +161,19 @@ class PembiayaanOnlineController extends Controller
|
|||||||
'update_customer_bank' => true,
|
'update_customer_bank' => true,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if ($request->hasFile('bukti_akaun')) {
|
||||||
|
$file = $request->file('bukti_akaun');
|
||||||
|
if (!$file->isValid()) {
|
||||||
|
return redirect()->back()->with('error', 'Fail slip bank tidak sah.');
|
||||||
|
}
|
||||||
|
if ($file->getSize() > 4 * 1024 * 1024) {
|
||||||
|
return redirect()->back()->with('error', 'Saiz fail maksimum 4MB.');
|
||||||
|
}
|
||||||
|
$payload['bukti_akaun_data'] = base64_encode(file_get_contents($file->getRealPath()));
|
||||||
|
$payload['bukti_akaun_filename'] = $file->getClientOriginalName();
|
||||||
|
$payload['bukti_akaun_type'] = $file->getMimeType() ?: 'application/octet-stream';
|
||||||
|
}
|
||||||
|
|
||||||
$res = $this->api()
|
$res = $this->api()
|
||||||
->asForm()
|
->asForm()
|
||||||
->put($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id, $payload);
|
->put($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id, $payload);
|
||||||
@@ -125,7 +184,55 @@ class PembiayaanOnlineController extends Controller
|
|||||||
return redirect()->back()->with('error', $msg);
|
return redirect()->back()->with('error', $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('pembiayaan.online.pc')->with('message', 'Rekod dikemaskini.');
|
return redirect()->route('pembiayaan.online.pc')
|
||||||
|
->with('message', 'Rekod dikemaskini. Sila semak semula sebelum hantar ke Operasi.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC verifies one queue line before it can be submitted to Operasi.
|
||||||
|
*/
|
||||||
|
public function verifyLine(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->abortUnlessPembiayaanOnline();
|
||||||
|
$kodcaw = $this->kodcaw();
|
||||||
|
$api_url = config('api.url');
|
||||||
|
$auth_user = Auth::user();
|
||||||
|
|
||||||
|
$res = $this->api()
|
||||||
|
->asForm()
|
||||||
|
->post($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . '/verify', [
|
||||||
|
'pc_verified_by' => $auth_user['name'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$res->successful()) {
|
||||||
|
$body = $res->json();
|
||||||
|
$msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal semak rekod.';
|
||||||
|
return redirect()->back()->with('error', $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->route('pembiayaan.online.pc')->with('message', 'Rekod disahkan. Boleh dipilih untuk hantar ke Operasi.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo PC verification on a queue line.
|
||||||
|
*/
|
||||||
|
public function unverifyLine(Request $request, $id)
|
||||||
|
{
|
||||||
|
$this->abortUnlessPembiayaanOnline();
|
||||||
|
$kodcaw = $this->kodcaw();
|
||||||
|
$api_url = config('api.url');
|
||||||
|
|
||||||
|
$res = $this->api()
|
||||||
|
->asForm()
|
||||||
|
->post($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . '/unverify');
|
||||||
|
|
||||||
|
if (!$res->successful()) {
|
||||||
|
$body = $res->json();
|
||||||
|
$msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Gagal batal semakan.';
|
||||||
|
return redirect()->back()->with('error', $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->route('pembiayaan.online.pc')->with('message', 'Semakan dibatalkan. Sila semak semula sebelum hantar.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -259,17 +366,87 @@ class PembiayaanOnlineController extends Controller
|
|||||||
return redirect()->back()->with('error', 'Fail bukti kosong.');
|
return redirect()->back()->with('error', 'Fail bukti kosong.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$raw = $bukti['data'];
|
return $this->streamBase64File($bukti, 'bukti-' . $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC: view uploaded customer bank slip.
|
||||||
|
*/
|
||||||
|
public function viewBuktiAkaun($id)
|
||||||
|
{
|
||||||
|
$this->abortUnlessPembiayaanOnline();
|
||||||
|
$kodcaw = $this->kodcaw();
|
||||||
|
$res = $this->api()
|
||||||
|
->get(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . '/bukti-akaun');
|
||||||
|
|
||||||
|
if (!$res->successful()) {
|
||||||
|
$body = $res->json();
|
||||||
|
$msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Slip bank tidak dijumpai.';
|
||||||
|
return redirect()->back()->with('error', $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $res->json();
|
||||||
|
$file = $payload['file'] ?? null;
|
||||||
|
if (!$file || empty($file['data'])) {
|
||||||
|
return redirect()->back()->with('error', 'Fail slip bank kosong.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->streamBase64File($file, 'slip-bank-' . $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PC: view SAG for a queue line (does not mark SAG as printed).
|
||||||
|
*/
|
||||||
|
public function viewSag($id)
|
||||||
|
{
|
||||||
|
$this->abortUnlessPembiayaanOnline();
|
||||||
|
return $this->renderLineSag($this->kodcaw(), $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operasi: view uploaded customer bank slip.
|
||||||
|
*/
|
||||||
|
public function operasiViewBuktiAkaun($kodcaw, $id)
|
||||||
|
{
|
||||||
|
$res = $this->api()
|
||||||
|
->get(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . '/bukti-akaun');
|
||||||
|
|
||||||
|
if (!$res->successful()) {
|
||||||
|
$body = $res->json();
|
||||||
|
$msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Slip bank tidak dijumpai.';
|
||||||
|
return redirect()->back()->with('error', $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $res->json();
|
||||||
|
$file = $payload['file'] ?? null;
|
||||||
|
if (!$file || empty($file['data'])) {
|
||||||
|
return redirect()->back()->with('error', 'Fail slip bank kosong.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->streamBase64File($file, 'slip-bank-' . $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operasi: view SAG for a batch line.
|
||||||
|
*/
|
||||||
|
public function operasiViewSag($kodcaw, $id)
|
||||||
|
{
|
||||||
|
return $this->renderLineSag($kodcaw, $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function streamBase64File(array $file, $fallbackName)
|
||||||
|
{
|
||||||
|
$raw = $file['data'];
|
||||||
if (strpos($raw, 'base64,') !== false) {
|
if (strpos($raw, 'base64,') !== false) {
|
||||||
$raw = substr($raw, strpos($raw, 'base64,') + 7);
|
$raw = substr($raw, strpos($raw, 'base64,') + 7);
|
||||||
}
|
}
|
||||||
$binary = base64_decode($raw, true);
|
$binary = base64_decode($raw, true);
|
||||||
if ($binary === false) {
|
if ($binary === false) {
|
||||||
$binary = base64_decode($bukti['data']);
|
$binary = base64_decode($file['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = $bukti['type'] ?? 'application/octet-stream';
|
$type = $file['type'] ?? 'application/octet-stream';
|
||||||
$filename = $bukti['filename'] ?? ('bukti-' . $id);
|
$filename = $file['filename'] ?? $fallbackName;
|
||||||
|
|
||||||
return response($binary, 200, [
|
return response($binary, 200, [
|
||||||
'Content-Type' => $type,
|
'Content-Type' => $type,
|
||||||
@@ -277,6 +454,115 @@ class PembiayaanOnlineController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function renderLineSag($kodcaw, $id)
|
||||||
|
{
|
||||||
|
$api_url = config('api.url');
|
||||||
|
$res = $this->api()->get($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id);
|
||||||
|
if (!$res->successful()) {
|
||||||
|
$body = $res->json();
|
||||||
|
$msg = is_array($body) && isset($body['message']) ? $body['message'] : 'Rekod tidak dijumpai.';
|
||||||
|
return redirect()->back()->with('error', $msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
$line = $res->json();
|
||||||
|
$norujukan = is_array($line) ? trim((string) ($line['norujukan'] ?? '')) : '';
|
||||||
|
if ($norujukan === '') {
|
||||||
|
return redirect()->back()->with('error', 'No. SAG tidak dijumpai.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderSagByNorujukan($kodcaw, $norujukan);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderSagByNorujukan($kodcaw, $norujukan)
|
||||||
|
{
|
||||||
|
$api_url = config('api.url');
|
||||||
|
$auth_user = Auth::user();
|
||||||
|
$auth_username = $auth_user['name'] ?? '';
|
||||||
|
|
||||||
|
$gadai = $this->api()
|
||||||
|
->get($api_url . '/api/gadai/norujukan/' . $kodcaw . '/' . $norujukan)
|
||||||
|
->json();
|
||||||
|
$gadai_detail = is_array($gadai) ? ($gadai[0] ?? null) : null;
|
||||||
|
if (!is_array($gadai_detail) || empty($gadai_detail['norujukan'])) {
|
||||||
|
return redirect()->back()->with('error', 'SAG tidak dijumpai.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$kakitangan = \App\User::where([['role_harian', 'khazanah'], ['cawangan', $kodcaw]])->first();
|
||||||
|
|
||||||
|
$customer = $this->api()
|
||||||
|
->get($api_url . '/api/customers/' . ($gadai_detail['nokp'] ?? ''))
|
||||||
|
->json();
|
||||||
|
$customer_detail = is_array($customer) ? $customer : [];
|
||||||
|
|
||||||
|
$marhun = $this->api()
|
||||||
|
->get($api_url . '/api/marhun/' . $norujukan)
|
||||||
|
->json();
|
||||||
|
$marhun_detail = is_array($marhun) ? ($marhun[0] ?? []) : [];
|
||||||
|
if (!is_array($marhun_detail)) {
|
||||||
|
$marhun_detail = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$mutu = $this->api()
|
||||||
|
->get($api_url . '/api/marhun/mutu/sag', [
|
||||||
|
'kodcaw' => $kodcaw,
|
||||||
|
'norujukan' => $norujukan,
|
||||||
|
])
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$cawangan = $this->api()
|
||||||
|
->get($api_url . '/api/cawangan/detail/' . $kodcaw)
|
||||||
|
->json();
|
||||||
|
$cawangan_detail = is_array($cawangan) ? ($cawangan[0] ?? []) : [];
|
||||||
|
|
||||||
|
$kadar_ujrah = $this->api()
|
||||||
|
->get($api_url . '/api/kadarujrah/by_group_id/', [
|
||||||
|
'kodcaw' => $cawangan_detail['kodcaw'] ?? $kodcaw,
|
||||||
|
])
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$pembayaran_segera = 'https://pay.arrahn.com.my';
|
||||||
|
|
||||||
|
$komoditi = $this->api()->get($api_url . '/api/komuditi/check')->json();
|
||||||
|
$product = $this->api()
|
||||||
|
->get($api_url . '/api/komuditi/description', [
|
||||||
|
'kodproduk' => is_array($komoditi) ? ($komoditi['kodproduct'] ?? '') : '',
|
||||||
|
])
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$nilai = is_array($komoditi) ? (float) ($komoditi['nilai'] ?? 0) : 0;
|
||||||
|
$kuantiti = $nilai > 0 ? ((float) ($gadai_detail['pinjaman'] ?? 0) / $nilai) : 0;
|
||||||
|
|
||||||
|
if (($gadai_detail['tagbaru'] ?? 0) == 1) {
|
||||||
|
return view('print.sag_ujrah_3', compact(
|
||||||
|
'komoditi',
|
||||||
|
'product',
|
||||||
|
'kuantiti',
|
||||||
|
'gadai_detail',
|
||||||
|
'customer_detail',
|
||||||
|
'marhun_detail',
|
||||||
|
'cawangan_detail',
|
||||||
|
'api_url',
|
||||||
|
'pembayaran_segera',
|
||||||
|
'auth_username',
|
||||||
|
'mutu',
|
||||||
|
'kadar_ujrah',
|
||||||
|
'kakitangan'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('print.sag', compact(
|
||||||
|
'gadai_detail',
|
||||||
|
'customer_detail',
|
||||||
|
'marhun_detail',
|
||||||
|
'cawangan_detail',
|
||||||
|
'api_url',
|
||||||
|
'pembayaran_segera',
|
||||||
|
'auth_username',
|
||||||
|
'mutu',
|
||||||
|
'kakitangan'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PC: tanda rekod PAID sebagai selesai semak / blast.
|
* PC: tanda rekod PAID sebagai selesai semak / blast.
|
||||||
*/
|
*/
|
||||||
@@ -309,7 +595,7 @@ class PembiayaanOnlineController extends Controller
|
|||||||
$n = $res->json()['dikemaskini'] ?? count($ids);
|
$n = $res->json()['dikemaskini'] ?? count($ids);
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('pembiayaan.online.pc.paid')
|
->route('pembiayaan.online.pc.paid')
|
||||||
->with('message', $n . ' rekod ditanda selesai semak/blast.');
|
->with('message', $n . ' rekod ditanda selesai. WhatsApp notis dihantar (nombor ujian jika bukan production).');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $except = [
|
protected $except = [
|
||||||
//
|
'internal/notifications',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,568 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\StaffNotification;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class NotificationService
|
||||||
|
{
|
||||||
|
const TYPE_PEMBIAYAAN_PENDING_PC = 'pembiayaan_online.pending_pc';
|
||||||
|
const TYPE_MODAL_PENDING_OPERASI = 'modal_online.pending_operasi';
|
||||||
|
const TYPE_PEMBIAYAAN_BATCH_OPERASI = 'pembiayaan_online.batch_operasi';
|
||||||
|
const TYPE_PEMBIAYAAN_REJECTED_PC = 'pembiayaan_online.rejected_pc';
|
||||||
|
const TYPE_PEMBIAYAAN_PAID_PC = 'pembiayaan_online.paid_pc';
|
||||||
|
const TYPE_GADAI_KELULUSAN = 'gadai.kelulusan';
|
||||||
|
const TYPE_ANGGOTA_PENDING_OPERASI = 'anggota.pending_operasi';
|
||||||
|
const TYPE_ALIRAN_TUNAI_PENDING = 'aliran_tunai.pending_khazanah';
|
||||||
|
const TYPE_ALIRAN_TUNAI_DECIDED = 'aliran_tunai.decided_teller';
|
||||||
|
const GADAI_KELULUSAN_MIN = 10000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create one inbox row per staff matching role + branch.
|
||||||
|
*
|
||||||
|
* @param string $role
|
||||||
|
* @param string $kodcaw
|
||||||
|
* @param array $payload
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function notifyRoleAtCawangan($role, $kodcaw, array $payload)
|
||||||
|
{
|
||||||
|
$users = User::query()
|
||||||
|
->where('roles', $role)
|
||||||
|
->where('cawangan', $kodcaw)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$created = collect();
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$created->push($this->notifyUser($user, $kodcaw, $role, $payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create one inbox row per staff matching role (any branch). For HQ like operasi.
|
||||||
|
*
|
||||||
|
* @param string $role
|
||||||
|
* @param array $payload
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function notifyRole($role, array $payload)
|
||||||
|
{
|
||||||
|
$kodcaw = isset($payload['cawangan']) ? $payload['cawangan'] : null;
|
||||||
|
$users = User::query()->where('roles', $role)->get();
|
||||||
|
|
||||||
|
$created = collect();
|
||||||
|
foreach ($users as $user) {
|
||||||
|
$created->push($this->notifyUser($user, $kodcaw, $role, $payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for api_arrahn (and local callers). Builds title/url from type when omitted.
|
||||||
|
*
|
||||||
|
* @param array $input
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function dispatch(array $input)
|
||||||
|
{
|
||||||
|
$type = isset($input['type']) ? $input['type'] : '';
|
||||||
|
$kodcaw = isset($input['cawangan']) ? $input['cawangan'] : null;
|
||||||
|
$audience = isset($input['audience']) && is_array($input['audience']) ? $input['audience'] : [];
|
||||||
|
$role = isset($audience['role']) ? $audience['role'] : null;
|
||||||
|
$data = isset($input['data']) && is_array($input['data']) ? $input['data'] : [];
|
||||||
|
|
||||||
|
if ($type === self::TYPE_ALIRAN_TUNAI_PENDING && $kodcaw) {
|
||||||
|
return $this->notifyAliranTunaiPending($kodcaw, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $this->payloadForType($type, $kodcaw, $data);
|
||||||
|
|
||||||
|
if (!empty($input['title'])) {
|
||||||
|
$payload['title'] = $input['title'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('body', $input) && $input['body'] !== null && $input['body'] !== '') {
|
||||||
|
$payload['body'] = $input['body'];
|
||||||
|
}
|
||||||
|
if (!empty($input['url'])) {
|
||||||
|
$payload['url'] = $input['url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($role === 'operasi') {
|
||||||
|
return $this->notifyRole('operasi', $payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($role && $kodcaw) {
|
||||||
|
return $this->notifyRoleAtCawangan($role, $kodcaw, $payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gadai >= RM10,000: inbox for PC/PPC at the branch and all operasi.
|
||||||
|
*
|
||||||
|
* @param string $kodcaw
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function notifyGadaiKelulusan($kodcaw, array $data)
|
||||||
|
{
|
||||||
|
$pinjaman = isset($data['pinjaman']) ? (float) $data['pinjaman'] : 0;
|
||||||
|
if ($pinjaman < self::GADAI_KELULUSAN_MIN) {
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $this->payloadForType(self::TYPE_GADAI_KELULUSAN, $kodcaw, $data);
|
||||||
|
|
||||||
|
$created = collect();
|
||||||
|
foreach (['pc', 'ppc'] as $role) {
|
||||||
|
$created = $created->merge(
|
||||||
|
$this->notifyRoleAtCawangan($role, $kodcaw, array_merge($payload, [
|
||||||
|
'url' => '/kelulusan',
|
||||||
|
]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $created->merge(
|
||||||
|
$this->notifyRole('operasi', array_merge($payload, [
|
||||||
|
'url' => '/operasi/kelulusan',
|
||||||
|
]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teller pendahuluan/serahan: inbox for PC/PPC at the branch.
|
||||||
|
*
|
||||||
|
* @param string $kodcaw
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function notifyAliranTunaiPending($kodcaw, array $data)
|
||||||
|
{
|
||||||
|
$payload = $this->payloadForType(self::TYPE_ALIRAN_TUNAI_PENDING, $kodcaw, $data);
|
||||||
|
|
||||||
|
$created = collect();
|
||||||
|
foreach (['pc', 'ppc'] as $role) {
|
||||||
|
$created = $created->merge($this->notifyRoleAtCawangan($role, $kodcaw, $payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Khazanah lulus/batal: inbox for the teller who requested cash.
|
||||||
|
*
|
||||||
|
* @param string $kodcaw
|
||||||
|
* @param string $tellerName
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function notifyAliranTunaiDecided($kodcaw, $tellerName, array $data)
|
||||||
|
{
|
||||||
|
$tellerName = trim((string) $tellerName);
|
||||||
|
if ($tellerName === '') {
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$payload = $this->payloadForType(self::TYPE_ALIRAN_TUNAI_DECIDED, $kodcaw, $data);
|
||||||
|
|
||||||
|
$user = User::query()
|
||||||
|
->where('name', $tellerName)
|
||||||
|
->where('cawangan', $kodcaw)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
$user = User::query()->where('name', $tellerName)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return collect([$this->notifyUser($user, $kodcaw, $user->roles, $payload)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $type
|
||||||
|
* @param string|null $kodcaw
|
||||||
|
* @param array $data
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function payloadForType($type, $kodcaw, array $data)
|
||||||
|
{
|
||||||
|
if ($type === self::TYPE_MODAL_PENDING_OPERASI) {
|
||||||
|
$jenis = isset($data['jenis']) ? strtoupper((string) $data['jenis']) : 'HAD';
|
||||||
|
$label = $jenis === 'TOPUP' ? 'tambah modal' : 'had modal';
|
||||||
|
$nama = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
||||||
|
$amaun = number_format(isset($data['amaun']) ? (float) $data['amaun'] : 0, 2);
|
||||||
|
$oleh = isset($data['dimohon_oleh']) ? trim((string) $data['dimohon_oleh']) : '';
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Permohonan modal online',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s mohon %s RM %s%s',
|
||||||
|
$nama,
|
||||||
|
$label,
|
||||||
|
$amaun,
|
||||||
|
$oleh !== '' ? ' — '.$oleh : ''
|
||||||
|
),
|
||||||
|
'url' => '/pembiayaan-online/operasi/topup',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_PEMBIAYAAN_BATCH_OPERASI) {
|
||||||
|
$nama = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
||||||
|
$batchNo = !empty($data['batch_no']) ? $data['batch_no'] : 'batch';
|
||||||
|
$batchId = isset($data['batch_id']) ? $data['batch_id'] : null;
|
||||||
|
$submitted = isset($data['submitted_count']) ? (int) $data['submitted_count'] : 0;
|
||||||
|
$jumlah = number_format(isset($data['jumlah_keseluruhan']) ? (float) $data['jumlah_keseluruhan'] : 0, 2);
|
||||||
|
$oleh = isset($data['pc_submitted_by']) ? trim((string) $data['pc_submitted_by']) : '';
|
||||||
|
$appended = !empty($data['appended']);
|
||||||
|
|
||||||
|
if ($appended) {
|
||||||
|
$body = sprintf(
|
||||||
|
'%s tambah %d rekod ke %s (RM %s)%s',
|
||||||
|
$nama,
|
||||||
|
$submitted,
|
||||||
|
$batchNo,
|
||||||
|
$jumlah,
|
||||||
|
$oleh !== '' ? ' — '.$oleh : ''
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$body = sprintf(
|
||||||
|
'%s hantar %s — %d rekod (RM %s)%s',
|
||||||
|
$nama,
|
||||||
|
$batchNo,
|
||||||
|
$submitted,
|
||||||
|
$jumlah,
|
||||||
|
$oleh !== '' ? ' — '.$oleh : ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Batch pembiayaan online',
|
||||||
|
'body' => $body,
|
||||||
|
'url' => ($kodcaw && $batchId)
|
||||||
|
? '/pembiayaan-online/operasi/'.$kodcaw.'/batches/'.$batchId
|
||||||
|
: '/pembiayaan-online/operasi',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_PEMBIAYAAN_REJECTED_PC) {
|
||||||
|
$norujukan = !empty($data['norujukan']) ? $data['norujukan'] : 'rekod';
|
||||||
|
$reason = isset($data['reject_reason']) ? trim((string) $data['reject_reason']) : '';
|
||||||
|
$amaun = number_format(isset($data['pinjaman']) ? (float) $data['pinjaman'] : 0, 2);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Pembiayaan online ditolak',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s (RM %s) ditolak%s',
|
||||||
|
$norujukan,
|
||||||
|
$amaun,
|
||||||
|
$reason !== '' ? ' — '.$reason : ''
|
||||||
|
),
|
||||||
|
'url' => '/pembiayaan-online/pc',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_PEMBIAYAAN_PAID_PC) {
|
||||||
|
$paidCount = isset($data['paid_count']) ? (int) $data['paid_count'] : 1;
|
||||||
|
$batchNo = !empty($data['batch_no']) ? $data['batch_no'] : '';
|
||||||
|
$norujukan = !empty($data['norujukan']) ? $data['norujukan'] : '';
|
||||||
|
$nama = isset($data['nama_pelanggan']) ? trim((string) $data['nama_pelanggan']) : '';
|
||||||
|
$amaun = number_format(
|
||||||
|
isset($data['pinjaman'])
|
||||||
|
? (float) $data['pinjaman']
|
||||||
|
: (isset($data['jumlah_keseluruhan']) ? (float) $data['jumlah_keseluruhan'] : 0),
|
||||||
|
2
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($paidCount > 1 || ($batchNo !== '' && $norujukan === '')) {
|
||||||
|
$body = sprintf(
|
||||||
|
'%d rekod telah dibayar%s (RM %s)',
|
||||||
|
$paidCount > 0 ? $paidCount : 0,
|
||||||
|
$batchNo !== '' ? ' dalam '.$batchNo : '',
|
||||||
|
$amaun
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$body = sprintf(
|
||||||
|
'%s telah dibayar (RM %s)%s',
|
||||||
|
$norujukan !== '' ? $norujukan : 'Rekod',
|
||||||
|
$amaun,
|
||||||
|
$nama !== '' ? ' — '.$nama : ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Pembiayaan online telah dibayar',
|
||||||
|
'body' => $body,
|
||||||
|
'url' => '/pembiayaan-online/pc/paid',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_ALIRAN_TUNAI_PENDING) {
|
||||||
|
$jenis = $this->aliranTunaiJenis($data);
|
||||||
|
$amaun = $this->aliranTunaiAmaun($data, $jenis);
|
||||||
|
$teller = isset($data['kodlaluan']) ? trim((string) $data['kodlaluan']) : '';
|
||||||
|
$label = $jenis === 'serahan' ? 'serahan' : 'pendahuluan';
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => $jenis === 'serahan' ? 'Permohonan serahan modal' : 'Permohonan pendahuluan',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s mohon %s RM %s',
|
||||||
|
$teller !== '' ? $teller : 'Teller',
|
||||||
|
$label,
|
||||||
|
number_format($amaun, 2)
|
||||||
|
),
|
||||||
|
'url' => $jenis === 'serahan' ? '/serahan' : '/pendahuluan',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_ALIRAN_TUNAI_DECIDED) {
|
||||||
|
$jenis = $this->aliranTunaiJenis($data);
|
||||||
|
$amaun = $this->aliranTunaiAmaun($data, $jenis);
|
||||||
|
$lulus = isset($data['pengesahan']) && strcasecmp((string) $data['pengesahan'], 'Lulus') === 0;
|
||||||
|
$label = 'Pendahuluan';
|
||||||
|
if ($jenis === 'serahan') {
|
||||||
|
$label = 'Serahan';
|
||||||
|
} elseif ($jenis === 'all') {
|
||||||
|
$label = 'Aliran tunai';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($lulus) {
|
||||||
|
$title = $label.' diluluskan';
|
||||||
|
$body = sprintf('%s RM %s telah diluluskan', $label, number_format($amaun, 2));
|
||||||
|
} else {
|
||||||
|
$title = $label.' tidak diluluskan';
|
||||||
|
$body = sprintf('Permohonan %s tidak diluluskan', strtolower($label));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => $title,
|
||||||
|
'body' => $body,
|
||||||
|
'url' => '/aliran_tunai',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_ANGGOTA_PENDING_OPERASI) {
|
||||||
|
$nokp = !empty($data['nokp']) ? $data['nokp'] : '';
|
||||||
|
$nama = isset($data['nama']) ? trim((string) $data['nama']) : '';
|
||||||
|
$teller = isset($data['teller']) ? trim((string) $data['teller']) : '';
|
||||||
|
$komen = isset($data['komen']) ? trim((string) $data['komen']) : '';
|
||||||
|
$namaCaw = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
||||||
|
$who = $nama !== '' ? $nama : 'pelanggan';
|
||||||
|
if ($nokp !== '') {
|
||||||
|
$who .= ' ('.$nokp.')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Permohonan assign anggota',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s — %s%s%s',
|
||||||
|
$namaCaw,
|
||||||
|
$who,
|
||||||
|
$teller !== '' ? ' — '.$teller : '',
|
||||||
|
$komen !== '' ? ' — '.$komen : ''
|
||||||
|
),
|
||||||
|
'url' => '/operasi/kelulusan/anggota',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type === self::TYPE_GADAI_KELULUSAN) {
|
||||||
|
$norujukan = !empty($data['norujukan']) ? $data['norujukan'] : 'gadai';
|
||||||
|
$amaun = number_format(isset($data['pinjaman']) ? (float) $data['pinjaman'] : 0, 2);
|
||||||
|
$teller = isset($data['teller']) ? trim((string) $data['teller']) : '';
|
||||||
|
$namaCaw = !empty($data['cawangan_nama']) ? $data['cawangan_nama'] : $kodcaw;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => 'Kelulusan gadai melebihi RM 10,000',
|
||||||
|
'body' => sprintf(
|
||||||
|
'%s — %s (RM %s)%s',
|
||||||
|
$namaCaw,
|
||||||
|
$norujukan,
|
||||||
|
$amaun,
|
||||||
|
$teller !== '' ? ' — '.$teller : ''
|
||||||
|
),
|
||||||
|
'url' => '/kelulusan',
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => $type,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'title' => isset($data['title']) ? $data['title'] : $type,
|
||||||
|
'body' => isset($data['body']) ? $data['body'] : null,
|
||||||
|
'url' => isset($data['url']) ? $data['url'] : null,
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return string pendahuluan|serahan|all
|
||||||
|
*/
|
||||||
|
protected function aliranTunaiJenis(array $data)
|
||||||
|
{
|
||||||
|
if (!empty($data['jenis'])) {
|
||||||
|
$jenis = strtolower(trim((string) $data['jenis']));
|
||||||
|
if ($jenis === 'serahan' || $jenis === 'pendahuluan' || $jenis === 'all') {
|
||||||
|
return $jenis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$modal = isset($data['modal']) ? (float) $data['modal'] : 0;
|
||||||
|
$serahan = isset($data['serahan']) ? (float) $data['serahan'] : 0;
|
||||||
|
if ($serahan > 0 && $modal <= 0) {
|
||||||
|
return 'serahan';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'pendahuluan';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param string $jenis
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
protected function aliranTunaiAmaun(array $data, $jenis)
|
||||||
|
{
|
||||||
|
if (isset($data['amaun']) && is_numeric($data['amaun'])) {
|
||||||
|
return (float) $data['amaun'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($jenis === 'serahan') {
|
||||||
|
return isset($data['serahan']) ? (float) $data['serahan'] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($data['modal']) ? (float) $data['modal'] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create one inbox row for a specific user.
|
||||||
|
*
|
||||||
|
* @param \App\User $user
|
||||||
|
* @param string|null $kodcaw
|
||||||
|
* @param string|null $role
|
||||||
|
* @param array $payload
|
||||||
|
* @return \App\StaffNotification
|
||||||
|
*/
|
||||||
|
public function notifyUser(User $user, $kodcaw, $role, array $payload)
|
||||||
|
{
|
||||||
|
return StaffNotification::create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'cawangan' => $kodcaw,
|
||||||
|
'role' => $role ?: $user->roles,
|
||||||
|
'type' => $payload['type'],
|
||||||
|
'title' => $payload['title'],
|
||||||
|
'body' => isset($payload['body']) ? $payload['body'] : null,
|
||||||
|
'url' => isset($payload['url']) ? $payload['url'] : null,
|
||||||
|
'data' => isset($payload['data']) ? $payload['data'] : null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\User $user
|
||||||
|
* @param int $limit
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function inboxFor(User $user, $limit = 20)
|
||||||
|
{
|
||||||
|
return StaffNotification::query()
|
||||||
|
->where('user_id', $user->id)
|
||||||
|
->orderByDesc('id')
|
||||||
|
->limit($limit)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\User $user
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function unreadCount(User $user)
|
||||||
|
{
|
||||||
|
return StaffNotification::query()
|
||||||
|
->where('user_id', $user->id)
|
||||||
|
->unread()
|
||||||
|
->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\User $user
|
||||||
|
* @param int $id
|
||||||
|
* @return \App\StaffNotification|null
|
||||||
|
*/
|
||||||
|
public function markAsRead(User $user, $id)
|
||||||
|
{
|
||||||
|
$notification = StaffNotification::query()
|
||||||
|
->where('user_id', $user->id)
|
||||||
|
->where('id', $id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$notification) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($notification->read_at === null) {
|
||||||
|
$notification->read_at = now();
|
||||||
|
$notification->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\User $user
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function markAllAsRead(User $user)
|
||||||
|
{
|
||||||
|
return StaffNotification::query()
|
||||||
|
->where('user_id', $user->id)
|
||||||
|
->unread()
|
||||||
|
->update(['read_at' => now()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\User $user
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function inboxPayload(User $user, $limit = 20)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'unread_count' => $this->unreadCount($user),
|
||||||
|
'notifications' => $this->inboxFor($user, $limit)->map(function (StaffNotification $notification) {
|
||||||
|
return $notification->toInboxArray();
|
||||||
|
})->values(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class StaffNotification extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'staff_notifications';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'cawangan',
|
||||||
|
'role',
|
||||||
|
'type',
|
||||||
|
'title',
|
||||||
|
'body',
|
||||||
|
'url',
|
||||||
|
'data',
|
||||||
|
'read_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'data' => 'array',
|
||||||
|
'read_at' => 'datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isRead()
|
||||||
|
{
|
||||||
|
return $this->read_at !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeUnread($query)
|
||||||
|
{
|
||||||
|
return $query->whereNull('read_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toInboxArray()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'type' => $this->type,
|
||||||
|
'title' => $this->title,
|
||||||
|
'body' => $this->body,
|
||||||
|
'url' => $this->url,
|
||||||
|
'read_at' => $this->read_at ? $this->read_at->toIso8601String() : null,
|
||||||
|
'created_at' => $this->created_at ? $this->created_at->toIso8601String() : null,
|
||||||
|
'created_at_human' => $this->created_at ? $this->created_at->diffForHumans() : null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,11 @@ class User extends Authenticatable
|
|||||||
return $this->hasOne(Cawangan::class, 'kodcaw', 'cawangan');
|
return $this->hasOne(Cawangan::class, 'kodcaw', 'cawangan');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function staffNotifications()
|
||||||
|
{
|
||||||
|
return $this->hasMany(StaffNotification::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function canImpersonate(): bool
|
public function canImpersonate(): bool
|
||||||
{
|
{
|
||||||
return in_array($this->roles ?? '', ['admin'], true);
|
return in_array($this->roles ?? '', ['admin'], true);
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'internal_secret' => env('INTERNAL_NOTIFICATION_SECRET', ''),
|
||||||
|
];
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateStaffNotificationsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('staff_notifications', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('user_id');
|
||||||
|
$table->string('cawangan', 20)->nullable();
|
||||||
|
$table->string('role', 30)->nullable();
|
||||||
|
$table->string('type', 80);
|
||||||
|
$table->string('title');
|
||||||
|
$table->text('body')->nullable();
|
||||||
|
$table->string('url', 500)->nullable();
|
||||||
|
$table->text('data')->nullable();
|
||||||
|
$table->timestamp('read_at')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->index(['user_id', 'read_at']);
|
||||||
|
$table->index(['cawangan', 'type']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('staff_notifications');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -559,7 +559,7 @@
|
|||||||
function cetaklaporanalirantunai()
|
function cetaklaporanalirantunai()
|
||||||
{
|
{
|
||||||
let urlroute = '{{ route("laporan.alirantunai") }}';
|
let urlroute = '{{ route("laporan.alirantunai") }}';
|
||||||
window.location.href = api_url + urlroute;
|
window.location.href = urlroute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -412,7 +412,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
|
|||||||
@@ -541,7 +541,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
|
|||||||
@@ -131,7 +131,8 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody></tbody>
|
<tbody>
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -437,7 +437,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
|
|||||||
@@ -390,14 +390,14 @@
|
|||||||
<x-datatable
|
<x-datatable
|
||||||
id="myTable"
|
id="myTable"
|
||||||
filename="SAG_Baru"
|
filename="SAG_Baru"
|
||||||
:columns="['Bil', 'No Rujukan', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Borang Online']"
|
:columns="['Bil', 'No Rujukan', 'Cara Terima', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Borang Online']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade {{ $activate_pane_SAG_lama }}" id="nav-xtawarruq" role="tabpanel" aria-labelledby="nav-xtawarruq-tab">
|
<div class="tab-pane fade {{ $activate_pane_SAG_lama }}" id="nav-xtawarruq" role="tabpanel" aria-labelledby="nav-xtawarruq-tab">
|
||||||
<x-datatable
|
<x-datatable
|
||||||
id="xtawarruq"
|
id="xtawarruq"
|
||||||
filename="SAG_Lama"
|
filename="SAG_Lama"
|
||||||
:columns="['Bil', 'No Rujukan', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Borang Online']"
|
:columns="['Bil', 'No Rujukan', 'Cara Terima', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Borang Online']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -712,13 +712,35 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
var min_komoditi = "{{ $min_komoditi }}";
|
var min_komoditi = "{{ $min_komoditi }}";
|
||||||
$('#daftar_gadai').on('click', function() {
|
console.log('test api_arrahnbid: ', api_arrahnbid);
|
||||||
|
$('#daftar_gadai').on('click', async function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
if ($(this).prop('disabled')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$("#daftar_gadai").prop('disabled', true);
|
$("#daftar_gadai").prop('disabled', true);
|
||||||
|
|
||||||
|
var bakiLelong = Number(@json((float) $bakilelong));
|
||||||
|
if (bakiLelong > 0) {
|
||||||
|
var confirmation = await Swal.fire({
|
||||||
|
icon: 'warning',
|
||||||
|
title: 'Baki Lelong',
|
||||||
|
text: 'Pelanggan mempunyai baki lelong, teruskan gadai?',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Teruskan',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
focusCancel: true
|
||||||
|
});
|
||||||
|
if (!(confirmation.isConfirmed || confirmation.value === true)) {
|
||||||
|
$("#daftar_gadai").prop('disabled', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
var noic = $('#noic').val();
|
var noic = $('#noic').val();
|
||||||
var iclama = "{{ $customer_info['kplama'] }}";
|
var iclama = "{{ $customer_info['kplama'] }}";
|
||||||
var icbaru = "{{ $customer_info['kpbaru'] }}";
|
var icbaru = "{{ $customer_info['kpbaru'] }}";
|
||||||
@@ -817,6 +839,10 @@
|
|||||||
return '{{ url("/gadai/borang-pengesahan-online") }}/' + encodeURIComponent(norujukan);
|
return '{{ url("/gadai/borang-pengesahan-online") }}/' + encodeURIComponent(norujukan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatCaraTerima(value) {
|
||||||
|
return String(value || 'TUNAI').toUpperCase() === 'ONLINE' ? 'Online' : 'Tunai';
|
||||||
|
}
|
||||||
|
|
||||||
function cetakBorangOnlineCell(gadai_detail) {
|
function cetakBorangOnlineCell(gadai_detail) {
|
||||||
var cara = String(gadai_detail['cara_terima'] || '').toUpperCase();
|
var cara = String(gadai_detail['cara_terima'] || '').toUpperCase();
|
||||||
if (cara !== 'ONLINE') {
|
if (cara !== 'ONLINE') {
|
||||||
@@ -1133,6 +1159,13 @@
|
|||||||
text: 'Pembiayaan Sedang Dilelong..'
|
text: 'Pembiayaan Sedang Dilelong..'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Amaran',
|
||||||
|
text: 'Tidak dapat semak status lelong. Sila cuba semula.'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1198,13 +1231,14 @@
|
|||||||
let table_norujukan = gadai_detail["norujukan"];
|
let table_norujukan = gadai_detail["norujukan"];
|
||||||
if (gadai_detail["percentpinj"] != 0)
|
if (gadai_detail["percentpinj"] != 0)
|
||||||
xtawarruq.row.add([
|
xtawarruq.row.add([
|
||||||
'<input type="radio" value=' + gadai_detail["norujukan"] +
|
'<input type="radio" value="' + gadai_detail["norujukan"] +
|
||||||
' name="belum"/>',
|
'" name="belum" data-cara-terima="' + (gadai_detail['cara_terima'] || '') + '"/>',
|
||||||
'<a href="#" onclick="checkserah(this)" data-pinjaman=' +
|
'<a href="#" onclick="checkserah(this)" data-pinjaman=' +
|
||||||
gadai_detail['pinjaman'] + ' data-hargajualan=' +
|
gadai_detail['pinjaman'] + ' data-hargajualan=' +
|
||||||
gadai_detail['hargajualan'] + ' data-norujukan=' +
|
gadai_detail['hargajualan'] + ' data-norujukan=' +
|
||||||
gadai_detail['norujukan'] + ' data-url=' + urlroute + '>' +
|
gadai_detail['norujukan'] + ' data-url=' + urlroute + '>' +
|
||||||
gadai_detail['norujukan'] + '</a>',
|
gadai_detail['norujukan'] + '</a>',
|
||||||
|
formatCaraTerima(gadai_detail['cara_terima']),
|
||||||
gadai_detail['t_gadai'],
|
gadai_detail['t_gadai'],
|
||||||
tarikh_matang,
|
tarikh_matang,
|
||||||
'RM ' + formatter.format(gadai_detail['bakihargajualan']),
|
'RM ' + formatter.format(gadai_detail['bakihargajualan']),
|
||||||
@@ -1216,6 +1250,7 @@
|
|||||||
'RM ' + formatter.format(upahsemasa),
|
'RM ' + formatter.format(upahsemasa),
|
||||||
'<div style="white-space: nowrap; color:red; font-weight: bolder">' +
|
'<div style="white-space: nowrap; color:red; font-weight: bolder">' +
|
||||||
taglel + '</div>',
|
taglel + '</div>',
|
||||||
|
cetakBorangOnlineCell(gadai_detail),
|
||||||
]).draw();
|
]).draw();
|
||||||
} else {
|
} else {
|
||||||
var taglel = '';
|
var taglel = '';
|
||||||
@@ -1256,6 +1291,7 @@
|
|||||||
gadai_detail['hargajualan'] + ' data-norujukan=' +
|
gadai_detail['hargajualan'] + ' data-norujukan=' +
|
||||||
gadai_detail['norujukan'] + ' data-url=' + urlroute + '>' +
|
gadai_detail['norujukan'] + ' data-url=' + urlroute + '>' +
|
||||||
gadai_detail['norujukan'] + '</a>',
|
gadai_detail['norujukan'] + '</a>',
|
||||||
|
formatCaraTerima(gadai_detail['cara_terima']),
|
||||||
gadai_detail['t_gadai'],
|
gadai_detail['t_gadai'],
|
||||||
tarikh_matang,
|
tarikh_matang,
|
||||||
'RM ' + formatter.format(gadai_detail['bakihargajualan']),
|
'RM ' + formatter.format(gadai_detail['bakihargajualan']),
|
||||||
@@ -2031,7 +2067,7 @@
|
|||||||
harini.setHours(0, 0, 0, 0);
|
harini.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
||||||
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(2)').text();
|
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(3)').text();
|
||||||
let tarikhgadai2 = new Date(test1);
|
let tarikhgadai2 = new Date(test1);
|
||||||
tarikhgadai2.setHours(0, 0, 0, 0);
|
tarikhgadai2.setHours(0, 0, 0, 0);
|
||||||
if (+harini !== +tarikhgadai2) {
|
if (+harini !== +tarikhgadai2) {
|
||||||
@@ -2448,7 +2484,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
||||||
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(2)').text();
|
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(3)').text();
|
||||||
let tarikhgadai2 = new Date(test1);
|
let tarikhgadai2 = new Date(test1);
|
||||||
tarikhgadai2.setHours(0, 0, 0, 0);
|
tarikhgadai2.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Online (Akaun Bank)</h1>
|
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Atas Talian (Online)</h1>
|
||||||
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
|
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Cara Terima Pembiayaan</th>
|
<th>Cara Terima Pembiayaan</th>
|
||||||
<td>Online (kredit ke akaun bank) — bukan tunai</td>
|
<td>Atas Talian (Online)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Teller</th>
|
<th>Teller</th>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<div class="form-group row col-12">
|
<div class="form-group row col-12">
|
||||||
<input type="hidden" name="kodcaw" id="kodcaw" value="{{$cawangan_info['kodcaw']}}">
|
<input type="hidden" name="kodcaw" id="kodcaw" value="{{$cawangan_info['kodcaw']}}">
|
||||||
<input type="hidden" id="pembiayaan_online_enabled" value="{{ !empty(($cawangan_info['features'] ?? [])['pembiayaan_online']) ? '1' : '0' }}">
|
<input type="hidden" id="pembiayaan_online_enabled" value="{{ !empty(($cawangan_info['features'] ?? [])['pembiayaan_online']) ? '1' : '0' }}">
|
||||||
|
<input type="hidden" id="rebet_annur_enabled" value="{{ !empty(($cawangan_info['features'] ?? [])['rebet_annur']) ? '1' : '0' }}">
|
||||||
<input type="hidden" name="nokp" id="nokp" value="{{ $customer_info['kpbaru'] }}">
|
<input type="hidden" name="nokp" id="nokp" value="{{ $customer_info['kpbaru'] }}">
|
||||||
<input type="hidden" name="tag_anggota" id="tag_anggota" value="{{ $customer_info['tag_anggota'] ?? 0 }}">
|
<input type="hidden" name="tag_anggota" id="tag_anggota" value="{{ $customer_info['tag_anggota'] ?? 0 }}">
|
||||||
|
|
||||||
@@ -186,6 +187,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</diV>
|
</diV>
|
||||||
</div>
|
</div>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
Kadar Rebet
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input type="text" class="form-control" readonly name="rebate" id="rebate">
|
||||||
|
<input type="text" class="form-control" readonly name="kadar_rebate" id="kadar_rebate">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@@ -232,9 +246,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<input class="form-check-input" type="radio" name="cara_terima" id="cara_terima_online" value="ONLINE">
|
<input class="form-check-input" type="radio" name="cara_terima" id="cara_terima_online" value="ONLINE">
|
||||||
<label class="form-check-label" for="cara_terima_online">Online (Akaun Bank)</label>
|
<label class="form-check-label" for="cara_terima_online">Atas Talian (Online)</label>
|
||||||
</div>
|
</div>
|
||||||
<small class="form-text text-muted">Pilihan Online untuk pembiayaan RM5,000 – RM50,000 sahaja.</small>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="bank_online_section" style="display:none;">
|
<div id="bank_online_section" style="display:none;">
|
||||||
@@ -292,6 +305,9 @@
|
|||||||
<a href="{{ route('gadai.batal',['norujukan'=>$norujukan]) }}" class="float-right btn btn-danger mr-2">Batal</a>
|
<a href="{{ route('gadai.batal',['norujukan'=>$norujukan]) }}" class="float-right btn btn-danger mr-2">Batal</a>
|
||||||
<input type="submit" name="terima_gadai" id="terima_gadai" class="float-right btn btn-primary mr-2" value="Terima">
|
<input type="submit" name="terima_gadai" id="terima_gadai" class="float-right btn btn-primary mr-2" value="Terima">
|
||||||
<button type="button" id="cetak_borang_online" class="float-right btn btn-info mr-2" style="display:none;">Cetak Borang</button>
|
<button type="button" id="cetak_borang_online" class="float-right btn btn-info mr-2" style="display:none;">Cetak Borang</button>
|
||||||
|
<div id="cetak_borang_hint" class="text-danger text-right mt-2" style="clear:both; display:none;">
|
||||||
|
Sila cetak borang pengesahan pelanggan dahulu
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -398,6 +414,9 @@
|
|||||||
<script>
|
<script>
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw_ujrah = "<?php echo $cawangan_info['kodcaw'] ?>";
|
var kodcaw_ujrah = "<?php echo $cawangan_info['kodcaw'] ?>";
|
||||||
|
const MIN_PINJAMAN = {{ \App\Http\Controllers\GadaianController::MIN_PINJAMAN }};
|
||||||
|
const MAX_PINJAMAN = {{ \App\Http\Controllers\GadaianController::MAX_PINJAMAN }};
|
||||||
|
var printedBorang = @json($borang_online_printed ?? null);
|
||||||
$('form input').keydown(function (e) {
|
$('form input').keydown(function (e) {
|
||||||
if (e.keyCode == 13) {
|
if (e.keyCode == 13) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -409,6 +428,13 @@
|
|||||||
$(document).on("keydown", disableF5);
|
$(document).on("keydown", disableF5);
|
||||||
var norujukan = $('#norujukan').val();
|
var norujukan = $('#norujukan').val();
|
||||||
getMarhun(norujukan);
|
getMarhun(norujukan);
|
||||||
|
@if(session('error'))
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Amaran!',
|
||||||
|
text: @json(session('error'))
|
||||||
|
});
|
||||||
|
@endif
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:'GET',
|
method:'GET',
|
||||||
@@ -789,6 +815,26 @@
|
|||||||
$('#ujrah').val(formatter.format(getRoundedMethod(array_keuntungan['ujrah']).toFixed(2)));
|
$('#ujrah').val(formatter.format(getRoundedMethod(array_keuntungan['ujrah']).toFixed(2)));
|
||||||
$('#onepercent').val(formatter.format(getRoundedMethod(array_keuntungan['onepercent']).toFixed(2)));
|
$('#onepercent').val(formatter.format(getRoundedMethod(array_keuntungan['onepercent']).toFixed(2)));
|
||||||
|
|
||||||
|
if ($('#rebet_annur_enabled').val() === '1') {
|
||||||
|
var rebate, kadar_rebate;
|
||||||
|
if (pinjaman < 20000) {
|
||||||
|
rebate = keuntungan_sebulan * 0.05;
|
||||||
|
kadar_rebate = 5;
|
||||||
|
} else if (pinjaman >= 20000 && pinjaman <= 50000) {
|
||||||
|
rebate = keuntungan_sebulan * 0.10;
|
||||||
|
kadar_rebate = 10;
|
||||||
|
} else if (pinjaman > 50000 && pinjaman <= 100000) {
|
||||||
|
rebate = keuntungan_sebulan * 0.15;
|
||||||
|
kadar_rebate = 15;
|
||||||
|
} else {
|
||||||
|
rebate = keuntungan_sebulan * 0.20;
|
||||||
|
kadar_rebate = 20;
|
||||||
|
}
|
||||||
|
rebate = getRoundedMethod(rebate);
|
||||||
|
$('#rebate').val(formatter.format(rebate.toFixed(2)));
|
||||||
|
$('#kadar_rebate').val(formatter.format(kadar_rebate.toFixed(2)) + ' %');
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const formatter = new Intl.NumberFormat('en-US', {
|
const formatter = new Intl.NumberFormat('en-US', {
|
||||||
@@ -1266,9 +1312,54 @@
|
|||||||
.then(response => response.json());
|
.then(response => response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function currentBorangFields() {
|
||||||
|
var pinjaman = Number(String($('#pinjaman').val() || '').replace(/,/g, ''));
|
||||||
|
if (!isFinite(pinjaman)) {
|
||||||
|
pinjaman = 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
norujukan: ($('#norujukan_gadai').val() || $('#norujukan').val() || '').trim(),
|
||||||
|
pinjaman: pinjaman.toFixed(2),
|
||||||
|
kodbank: ($('#gadai_kodbank').val() || '').trim().toUpperCase(),
|
||||||
|
noakaun: ($('#gadai_noakaun').val() || '').replace(/\s+/g, ''),
|
||||||
|
nama_akaun: ($('#gadai_nama_akaun').val() || $('input[name="nama_pelanggan"]').val() || '').trim().toUpperCase()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOnlineCaraTerima() {
|
||||||
|
var pembiayaanOnlineEnabled = $('#pembiayaan_online_enabled').val() === '1';
|
||||||
|
var pinjaman = Number(String($('#pinjaman').val() || '').replace(/,/g, ''));
|
||||||
|
return pembiayaanOnlineEnabled
|
||||||
|
&& pinjaman >= MIN_PINJAMAN
|
||||||
|
&& pinjaman <= MAX_PINJAMAN
|
||||||
|
&& $('input[name="cara_terima"]:checked').val() === 'ONLINE';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMatchingPrint() {
|
||||||
|
if (!printedBorang) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var cur = currentBorangFields();
|
||||||
|
return printedBorang.norujukan === cur.norujukan
|
||||||
|
&& printedBorang.pinjaman === cur.pinjaman
|
||||||
|
&& printedBorang.kodbank === cur.kodbank
|
||||||
|
&& printedBorang.noakaun === cur.noakaun
|
||||||
|
&& printedBorang.nama_akaun === cur.nama_akaun;
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncTerimaButton() {
|
||||||
|
var lock = isOnlineCaraTerima() && !hasMatchingPrint();
|
||||||
|
$('#terima_gadai').prop('disabled', lock);
|
||||||
|
if (lock) {
|
||||||
|
$('#cetak_borang_hint').show();
|
||||||
|
} else {
|
||||||
|
$('#cetak_borang_hint').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleCaraTerima(pinjaman) {
|
function toggleCaraTerima(pinjaman) {
|
||||||
var pembiayaanOnlineEnabled = $('#pembiayaan_online_enabled').val() === '1';
|
var pembiayaanOnlineEnabled = $('#pembiayaan_online_enabled').val() === '1';
|
||||||
if (pembiayaanOnlineEnabled && pinjaman >= 5000 && pinjaman <= 50000) {
|
if (pembiayaanOnlineEnabled && pinjaman >= MIN_PINJAMAN && pinjaman <= MAX_PINJAMAN) {
|
||||||
$('#cara_terima_section').show();
|
$('#cara_terima_section').show();
|
||||||
toggleBankOnlineSection();
|
toggleBankOnlineSection();
|
||||||
} else {
|
} else {
|
||||||
@@ -1276,6 +1367,7 @@
|
|||||||
$('#bank_online_section').hide();
|
$('#bank_online_section').hide();
|
||||||
$('#cetak_borang_online').hide();
|
$('#cetak_borang_online').hide();
|
||||||
$('#cara_terima_tunai').prop('checked', true);
|
$('#cara_terima_tunai').prop('checked', true);
|
||||||
|
syncTerimaButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1290,16 +1382,20 @@
|
|||||||
$('#bank_online_section').hide();
|
$('#bank_online_section').hide();
|
||||||
$('#cetak_borang_online').hide();
|
$('#cetak_borang_online').hide();
|
||||||
}
|
}
|
||||||
|
syncTerimaButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on('change', 'input[name="cara_terima"]', function () {
|
$(document).on('change', 'input[name="cara_terima"]', function () {
|
||||||
toggleBankOnlineSection();
|
toggleBankOnlineSection();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('change', '#gadai_kodbank', function () {
|
$(document).on('change input', '#gadai_kodbank, #gadai_noakaun, #gadai_nama_akaun', function () {
|
||||||
$('#gadai_nama_bank').val($('#gadai_kodbank option:selected').data('nama') || '');
|
$('#gadai_nama_bank').val($('#gadai_kodbank option:selected').data('nama') || '');
|
||||||
|
syncTerimaButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
syncTerimaButton();
|
||||||
|
|
||||||
$(document).on('click', '#cetak_borang_online', function () {
|
$(document).on('click', '#cetak_borang_online', function () {
|
||||||
var kodbank = $('#gadai_kodbank').val();
|
var kodbank = $('#gadai_kodbank').val();
|
||||||
var noakaun = ($('#gadai_noakaun').val() || '').trim();
|
var noakaun = ($('#gadai_noakaun').val() || '').trim();
|
||||||
@@ -1332,6 +1428,9 @@
|
|||||||
form.append($('<input>', { type: 'hidden', name: 'noakaun', value: noakaun }));
|
form.append($('<input>', { type: 'hidden', name: 'noakaun', value: noakaun }));
|
||||||
form.append($('<input>', { type: 'hidden', name: 'nama_akaun', value: namaAkaun }));
|
form.append($('<input>', { type: 'hidden', name: 'nama_akaun', value: namaAkaun }));
|
||||||
form.appendTo('body').trigger('submit').remove();
|
form.appendTo('body').trigger('submit').remove();
|
||||||
|
|
||||||
|
printedBorang = currentBorangFields();
|
||||||
|
syncTerimaButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getModalOnline() {
|
async function getModalOnline() {
|
||||||
@@ -1381,7 +1480,7 @@
|
|||||||
|
|
||||||
async function checkDisbursementFloat(pinjaman) {
|
async function checkDisbursementFloat(pinjaman) {
|
||||||
var cara = $('input[name="cara_terima"]:checked').val() || 'TUNAI';
|
var cara = $('input[name="cara_terima"]:checked').val() || 'TUNAI';
|
||||||
if (!(pinjaman >= 5000 && pinjaman <= 50000)) {
|
if (!(pinjaman >= MIN_PINJAMAN && pinjaman <= MAX_PINJAMAN)) {
|
||||||
cara = 'TUNAI';
|
cara = 'TUNAI';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,7 +1587,7 @@
|
|||||||
let bakiakhir = 0;
|
let bakiakhir = 0;
|
||||||
var kodcaw = $('#kodcaw').val();
|
var kodcaw = $('#kodcaw').val();
|
||||||
if(pinjaman == 0){
|
if(pinjaman == 0){
|
||||||
$("#terima_gadai").prop('disabled', false);
|
syncTerimaButton();
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
title: 'Amaran!',
|
title: 'Amaran!',
|
||||||
@@ -1497,6 +1596,16 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isOnlineCaraTerima() && !hasMatchingPrint()) {
|
||||||
|
syncTerimaButton();
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'warning',
|
||||||
|
title: 'Borang belum dicetak',
|
||||||
|
text: 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let floatOk = await checkDisbursementFloat(pinjaman);
|
let floatOk = await checkDisbursementFloat(pinjaman);
|
||||||
if (!floatOk) {
|
if (!floatOk) {
|
||||||
$("#terima_gadai").prop('disabled', false);
|
$("#terima_gadai").prop('disabled', false);
|
||||||
|
|||||||
@@ -219,78 +219,70 @@
|
|||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
|
|
||||||
<div class="row form-group justify-content-center">
|
<div class="row form-group justify-content-center">
|
||||||
<div class="col-3 mx-1">
|
<div class="col-4 px-2">
|
||||||
<div class="row">
|
<a href="{{ url('dashboard') }}" disabled
|
||||||
<a href="{{ url('dashboard') }}" disabled
|
class="btn btn-info btn-lg btn-block mb-3">Dashboard</a>
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Dashboard</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ url('kakitangan') }}"
|
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Kakitangan</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ url('kelulusan') }}" id="btnkelulusan"
|
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Kelulusan</a>
|
|
||||||
</div>
|
|
||||||
{{-- <div class="row">
|
|
||||||
<a href="{{ url('permohonan') }}" class="btn btn-danger btn-lg btn-block mb-3">Permohonan</a>
|
|
||||||
</div> --}}
|
|
||||||
<div class="row">
|
|
||||||
<a href="#" data-target="#denominasiShowModal" data-backdrop="static" data-keyboard="false"
|
|
||||||
data-toggle="modal" class="btn btn-info btn-lg btn-block mb-3">Denominasi</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
<a href="{{ route('khazanah.harga_emas') }}"
|
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Harga Emas</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-3 mx-1">
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ route('khazanah.pelanggan') }}"
|
<a href="{{ route('khazanah.pelanggan') }}"
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Pelanggan</a>
|
class="btn btn-info btn-lg btn-block mb-3">Pelanggan</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ route('lelong') }}" class="btn btn-info btn-lg btn-block mb-3">Lelong</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ url('kakitangan') }}"
|
||||||
|
class="btn btn-info btn-lg btn-block mb-3">Kakitangan</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
<a href="{{ route('laporan') }}" class="btn btn-info btn-lg btn-block mb-3">Laporan</a>
|
<a href="{{ route('laporan') }}" class="btn btn-info btn-lg btn-block mb-3">Laporan</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ url('panjar') }}" class="btn btn-info btn-lg btn-block mb-3">Perbelanjaan</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ url('kelulusan') }}" id="btnkelulusan"
|
||||||
|
class="btn btn-info btn-lg btn-block mb-3">Kelulusan</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
<a href="{{ url('menu') }}"
|
<a href="{{ url('menu') }}"
|
||||||
id="btn-khazanah"
|
id="btn-khazanah"
|
||||||
class="btn {{ $countkhazanah > 0 ? 'btn-danger' : 'btn-info' }} btn-lg btn-block mb-3">Khazanah</a>
|
class="btn {{ $countkhazanah > 0 ? 'btn-danger' : 'btn-info' }} btn-lg btn-block mb-3">Khazanah</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ url('alirantunai') }}" class="btn btn-info btn-lg btn-block mb-3">Aliran
|
||||||
|
Tunai</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="#" data-target="#denominasiShowModal" data-backdrop="static" data-keyboard="false"
|
||||||
|
data-toggle="modal" class="btn btn-info btn-lg btn-block mb-3">Denominasi</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
<a href="{{ url('pendahuluanserahan') }}"
|
<a href="{{ url('pendahuluanserahan') }}"
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Pendahuluan - Serahan</a>
|
class="btn btn-info btn-lg btn-block mb-3">Pendahuluan - Serahan</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ route('khazanah.bajet') }}" class="btn btn-info btn-lg btn-block mb-3">Bajet</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ route('khazanah.harga_emas') }}"
|
||||||
|
class="btn btn-info btn-lg btn-block mb-3">Harga Emas</a>
|
||||||
|
</div>
|
||||||
@if(!empty(($cawangan_info['features'] ?? [])['pembiayaan_online']))
|
@if(!empty(($cawangan_info['features'] ?? [])['pembiayaan_online']))
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
<a href="{{ route('pembiayaan.online.pc') }}"
|
<a href="{{ route('pembiayaan.online.pc') }}"
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Pembiayaan Online</a>
|
class="btn btn-info btn-lg btn-block mb-3">Pembiayaan Online</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-4 px-2">
|
||||||
|
<a href="{{ route('pembiayaan.online.pc.topup') }}"
|
||||||
|
class="btn btn-info btn-lg btn-block mb-3">Had / Modal Online</a>
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
<div class="row">
|
<div class="col-4 px-2">
|
||||||
<a href="{{ route('khazanah.indexwakil') }}"
|
<a href="{{ route('khazanah.indexwakil') }}"
|
||||||
class="btn btn-info btn-lg btn-block mb-3">Surat Wakil</a>
|
class="btn btn-info btn-lg btn-block mb-3">Surat Wakil</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 mx-1">
|
|
||||||
{{-- <div class="row">
|
|
||||||
<a href="#" class="btn btn-danger btn-lg btn-block mb-3">Capaian</a>
|
|
||||||
</div> --}}
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ route('lelong') }}" class="btn btn-info btn-lg btn-block mb-3">Lelong</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ url('panjar') }}" class="btn btn-info btn-lg btn-block mb-3">Perbelanjaan</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ url('alirantunai') }}" class="btn btn-info btn-lg btn-block mb-3">Aliran
|
|
||||||
Tunai</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a href="{{ route('khazanah.bajet') }}" class="btn btn-info btn-lg btn-block mb-3">Bajet</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -414,7 +414,7 @@
|
|||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var ppc = "{{ Auth::user()->name }}";
|
var ppc = "{{ Auth::user()->name }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
<th>No K/P</th>
|
<th>No K/P</th>
|
||||||
<th>Tarikh Pembiayaan</th>
|
<th>Tarikh Pembiayaan</th>
|
||||||
<th>No Rujukan</th>
|
<th>No Rujukan</th>
|
||||||
|
<th>Cara Terima</th>
|
||||||
<th>Pembiayaan (RM)</th>
|
<th>Pembiayaan (RM)</th>
|
||||||
<th>Keuntungan Lain-lain Caj (RM) </th>
|
<th>Keuntungan Lain-lain Caj (RM) </th>
|
||||||
<th>Keuntungan 1% (RM)</th>
|
<th>Keuntungan 1% (RM)</th>
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tfoot class="thead-dark">
|
<tfoot class="thead-dark">
|
||||||
<th colspan="5">TOTAL</th>
|
<th colspan="6">TOTAL</th>
|
||||||
<th id="pinjamantotal"></th>
|
<th id="pinjamantotal"></th>
|
||||||
<th id="ujrahtotal"></th>
|
<th id="ujrahtotal"></th>
|
||||||
<th id="onepercenttotal"></th>
|
<th id="onepercenttotal"></th>
|
||||||
@@ -300,6 +301,10 @@
|
|||||||
|
|
||||||
total_upah12 += upah12;
|
total_upah12 += upah12;
|
||||||
|
|
||||||
|
var caraTerima = String(gadai['cara_terima'] || 'TUNAI').toUpperCase() === 'ONLINE'
|
||||||
|
? 'Online'
|
||||||
|
: 'Tunai';
|
||||||
|
|
||||||
// Pastikan semua nilai ada sebelum add row
|
// Pastikan semua nilai ada sebelum add row
|
||||||
tablegadai.row.add([
|
tablegadai.row.add([
|
||||||
counter,
|
counter,
|
||||||
@@ -307,6 +312,7 @@
|
|||||||
gadai['nokp'] || '-',
|
gadai['nokp'] || '-',
|
||||||
gadai['t_gadai'] || '-',
|
gadai['t_gadai'] || '-',
|
||||||
gadai['norujukan'] || '-',
|
gadai['norujukan'] || '-',
|
||||||
|
caraTerima,
|
||||||
formatter.format(pinjaman),
|
formatter.format(pinjaman),
|
||||||
formatter.format(ujrah * 12),
|
formatter.format(ujrah * 12),
|
||||||
formatter.format(onepercent * 12),
|
formatter.format(onepercent * 12),
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
var api_url = "{{ api_url_for_browser() }}";
|
var api_url = "{{ api_url_for_browser() }}";
|
||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
|
|||||||
@@ -414,7 +414,7 @@
|
|||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var ppc = "{{ Auth::user()->name }}";
|
var ppc = "{{ Auth::user()->name }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,7 @@
|
|||||||
<th>Keuntungan</th>
|
<th>Keuntungan</th>
|
||||||
<th>Lelong</th>
|
<th>Lelong</th>
|
||||||
<th>Pembayaran Terakhir</th>
|
<th>Pembayaran Terakhir</th>
|
||||||
|
<th>Tarikh Ansuran Terkini</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@@ -204,6 +205,7 @@
|
|||||||
<th>Keuntungan</th>
|
<th>Keuntungan</th>
|
||||||
<th>Lelong</th>
|
<th>Lelong</th>
|
||||||
<th>Pembayaran Terakhir</th>
|
<th>Pembayaran Terakhir</th>
|
||||||
|
<th>Tarikh Ansuran Terkini</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
@@ -470,7 +472,7 @@
|
|||||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||||
var ppc = "{{ Auth::user()->name }}";
|
var ppc = "{{ Auth::user()->name }}";
|
||||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||||
var api_arrahnbid = "<?php echo config('app.api_arrahnbid') ?>";
|
var api_arrahnbid = @json($cawangan_info['api_arrahnbid'] ?? config('app.api_arrahnbid'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -634,6 +636,45 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tarikhAnsuranTerkini(transactions)
|
||||||
|
{
|
||||||
|
if (!Array.isArray(transactions)) {
|
||||||
|
throw new Error('Invalid transaction response');
|
||||||
|
}
|
||||||
|
return transactions.reduce(function(latest, transaction) {
|
||||||
|
if (transaction.trans_type !== 'A') return latest;
|
||||||
|
var date = String(transaction.created_at || '').slice(0, 10);
|
||||||
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return latest;
|
||||||
|
return date > latest ? date : latest;
|
||||||
|
}, '') || 'Tiada bayaran';
|
||||||
|
}
|
||||||
|
|
||||||
|
function muatTarikhAnsuranTerkini(row, norujukan)
|
||||||
|
{
|
||||||
|
var originalData = row.data();
|
||||||
|
function update(value) {
|
||||||
|
// Ignore responses for rows removed when the customer/table changes.
|
||||||
|
if (row.data() !== originalData) return;
|
||||||
|
var updatedData = originalData.slice();
|
||||||
|
updatedData[11] = value;
|
||||||
|
row.data(updatedData).draw(false);
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
method: 'get',
|
||||||
|
url: api_url + '/api/transaction/' + encodeURIComponent(norujukan),
|
||||||
|
success: function(transactions) {
|
||||||
|
try {
|
||||||
|
update(tarikhAnsuranTerkini(transactions));
|
||||||
|
} catch (error) {
|
||||||
|
update('Gagal dimuatkan');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
update('Gagal dimuatkan');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function gadaiTable(data,jenistebus){
|
function gadaiTable(data,jenistebus){
|
||||||
|
|
||||||
var counter = 1;
|
var counter = 1;
|
||||||
@@ -665,7 +706,15 @@
|
|||||||
var taglel = '';
|
var taglel = '';
|
||||||
if(gadai_detail['taglel'] == 1){
|
if(gadai_detail['taglel'] == 1){
|
||||||
if(tagarrahnbid == 1){
|
if(tagarrahnbid == 1){
|
||||||
taglel = gadai_detail['t_lelong'];
|
$.ajax({
|
||||||
|
method: "GET",
|
||||||
|
async: false,
|
||||||
|
url: api_arrahnbid + 'portalApi',
|
||||||
|
data: { norujukan: gadai_detail['norujukan'] },
|
||||||
|
success: function(data) {
|
||||||
|
taglel = (data && data.lelong && data.lelong.t_lelong) || '';
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:"GET",
|
method:"GET",
|
||||||
@@ -685,8 +734,8 @@
|
|||||||
let table_norujukan = gadai_detail["norujukan"];
|
let table_norujukan = gadai_detail["norujukan"];
|
||||||
// let radio_action = "onclick=checkCanChangeGadaianDetail(" + "'" + table_norujukan + "'" + ")";
|
// let radio_action = "onclick=checkCanChangeGadaianDetail(" + "'" + table_norujukan + "'" + ")";
|
||||||
|
|
||||||
if(gadai_detail["percentpinj"] != 0)
|
if(gadai_detail["percentpinj"] != 0) {
|
||||||
xtawarruq.row.add([
|
var ansuranRow = xtawarruq.row.add([
|
||||||
'<input type="radio" value='+ gadai_detail["norujukan"] + ' name="belum"/>',
|
'<input type="radio" value='+ gadai_detail["norujukan"] + ' name="belum"/>',
|
||||||
// '<a href="#" onclick="checkserah(this)" data-pinjaman='+ gadai_detail['pinjaman'] +' data-hargajualan='+ gadai_detail['hargajualan'] +' data-norujukan='+ gadai_detail['norujukan'] +' data-url=' + urlroute +'>' + gadai_detail['norujukan'] + '</a>',
|
// '<a href="#" onclick="checkserah(this)" data-pinjaman='+ gadai_detail['pinjaman'] +' data-hargajualan='+ gadai_detail['hargajualan'] +' data-norujukan='+ gadai_detail['norujukan'] +' data-url=' + urlroute +'>' + gadai_detail['norujukan'] + '</a>',
|
||||||
(function() {
|
(function() {
|
||||||
@@ -716,15 +765,24 @@
|
|||||||
let color = bayaranInfo.blocked ? 'red' : 'green';
|
let color = bayaranInfo.blocked ? 'red' : 'green';
|
||||||
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
||||||
bayaranInfo.tarikh + '</div>';
|
bayaranInfo.tarikh + '</div>';
|
||||||
})()
|
})(),
|
||||||
|
'Memuatkan...'
|
||||||
]).draw();
|
]).draw();
|
||||||
|
muatTarikhAnsuranTerkini(ansuranRow, gadai_detail['norujukan']);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
var taglel = '';
|
var taglel = '';
|
||||||
if(gadai_detail['taglel'] == 1){
|
if(gadai_detail['taglel'] == 1){
|
||||||
if(tagarrahnbid == 1){
|
if(tagarrahnbid == 1){
|
||||||
if(gadai_detail['t_lelong'] != null) {
|
$.ajax({
|
||||||
taglel = gadai_detail['t_lelong'];
|
method: "GET",
|
||||||
}
|
async: false,
|
||||||
|
url: api_arrahnbid + 'portalApi',
|
||||||
|
data: { norujukan: gadai_detail['norujukan'] },
|
||||||
|
success: function(data) {
|
||||||
|
taglel = (data && data.lelong && data.lelong.t_lelong) || '';
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method:"GET",
|
method:"GET",
|
||||||
@@ -743,7 +801,7 @@
|
|||||||
|
|
||||||
let table_norujukan = gadai_detail["norujukan"];
|
let table_norujukan = gadai_detail["norujukan"];
|
||||||
// let radio_action = "onclick=checkCanChangeGadaianDetail(" + "'" + table_norujukan + "'" + ")";
|
// let radio_action = "onclick=checkCanChangeGadaianDetail(" + "'" + table_norujukan + "'" + ")";
|
||||||
tablegadai.row.add([
|
var ansuranRow = tablegadai.row.add([
|
||||||
'<input type="radio" value='+ gadai_detail["norujukan"] + ' name="belum"/>',
|
'<input type="radio" value='+ gadai_detail["norujukan"] + ' name="belum"/>',
|
||||||
// '<a href="#" onclick="checkserah(this)" data-pinjaman='+ gadai_detail['pinjaman'] +' data-hargajualan='+ gadai_detail['hargajualan'] +' data-norujukan='+ gadai_detail['norujukan'] +' data-url=' + urlroute +'>' + gadai_detail['norujukan'] + '</a>',
|
// '<a href="#" onclick="checkserah(this)" data-pinjaman='+ gadai_detail['pinjaman'] +' data-hargajualan='+ gadai_detail['hargajualan'] +' data-norujukan='+ gadai_detail['norujukan'] +' data-url=' + urlroute +'>' + gadai_detail['norujukan'] + '</a>',
|
||||||
(function() {
|
(function() {
|
||||||
@@ -773,8 +831,10 @@
|
|||||||
let color = bayaranInfo.blocked ? 'red' : 'green';
|
let color = bayaranInfo.blocked ? 'red' : 'green';
|
||||||
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
||||||
bayaranInfo.tarikh + '</div>';
|
bayaranInfo.tarikh + '</div>';
|
||||||
})()
|
})(),
|
||||||
|
'Memuatkan...'
|
||||||
]).draw();
|
]).draw();
|
||||||
|
muatTarikhAnsuranTerkini(ansuranRow, gadai_detail['norujukan']);
|
||||||
}
|
}
|
||||||
}else if(jenistebus == "sudah_tebus"){
|
}else if(jenistebus == "sudah_tebus"){
|
||||||
|
|
||||||
|
|||||||
@@ -214,14 +214,16 @@
|
|||||||
v-pre
|
v-pre
|
||||||
style="color: {{ isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan 2' ? 'black' : '#1abc9c' }};">
|
style="color: {{ isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan 2' ? 'black' : '#1abc9c' }};">
|
||||||
<i id="bell" class="fa fa-bell"></i>
|
<i id="bell" class="fa fa-bell"></i>
|
||||||
|
<span id="staff-notification-badge" class="staff-notification-badge"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu dropdown-menu-right staff-notification-menu" aria-labelledby="navbarDropdown">
|
||||||
<div id="divbiasa">
|
<div id="divbiasa" class="d-none">
|
||||||
<a class="dropdown-item" id="linkz" href="#">
|
<a class="dropdown-item" id="linkz" href="#">
|
||||||
Tiada Data
|
Tiada Data
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@include('layouts.partials.notification_inbox')
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -281,7 +283,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@elseif($auth_user['role_harian'] == 'teller')
|
@elseif($auth_user['role_harian'] == 'teller' || $auth_user['roles'] == 'teller')
|
||||||
<li class="nav-item dropdown" style="margin-right:10px;">
|
<li class="nav-item dropdown" style="margin-right:10px;">
|
||||||
<a id="navbarDropdown"
|
<a id="navbarDropdown"
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
@@ -293,60 +295,13 @@
|
|||||||
v-pre
|
v-pre
|
||||||
style="color: {{ isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan' ? 'white' : (isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan 2' ? 'black' : '#1abc9c') }};">
|
style="color: {{ isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan' ? 'white' : (isset($cawangan_info['details_caw']) && $cawangan_info['details_caw'] == 'Putatan 2' ? 'black' : '#1abc9c') }};">
|
||||||
<i id="bell" class="fa fa-bell"></i>
|
<i id="bell" class="fa fa-bell"></i>
|
||||||
|
<span id="staff-notification-badge" class="staff-notification-badge"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu dropdown-menu-right staff-notification-menu" aria-labelledby="navbarDropdown">
|
||||||
<div id="divbiasa">
|
@include('layouts.partials.notification_inbox')
|
||||||
<a class="dropdown-item" id="gadailinkz" href="#">
|
|
||||||
Tiada Data
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{-- <script>
|
|
||||||
|
|
||||||
// Enable pusher logging - don't include this in production
|
|
||||||
// Pusher.logToConsole = true;
|
|
||||||
|
|
||||||
var pusher = new Pusher("{{ env('PUSHER_APP_KEY') }}", {
|
|
||||||
cluster: 'ap1',
|
|
||||||
encrypted: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var channel = pusher.subscribe('notifikasi-pembayaran');
|
|
||||||
channel.bind('trigger-pembayaran', function(data) {
|
|
||||||
let message = JSON.stringify(data);
|
|
||||||
|
|
||||||
$('#bell').css("color", "red");
|
|
||||||
$('#gadailinkz').text("Khazanah Serah Marhun Teller");
|
|
||||||
// $("#gadailinkz").attr("href", "{{ url('kelulusan') }}");
|
|
||||||
|
|
||||||
const Toast = Swal.mixin({
|
|
||||||
toast: true,
|
|
||||||
position: 'top-end',
|
|
||||||
showConfirmButton: false,
|
|
||||||
timer: 5000,
|
|
||||||
timerProgressBar: true,
|
|
||||||
didOpen: (toast) => {
|
|
||||||
toast.addEventListener('mouseenter', Swal.stopTimer)
|
|
||||||
toast.addEventListener('mouseleave', Swal.resumeTimer)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Toast.fire({
|
|
||||||
icon: 'error',
|
|
||||||
title: 'Notifikasi Pembayaran!'
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#navbarDropdown").click(function(){
|
|
||||||
$('#bell').css("color", "grey");
|
|
||||||
});
|
|
||||||
|
|
||||||
</script> --}}
|
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
@@ -446,30 +401,9 @@
|
|||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
@endif
|
@endif
|
||||||
|
@include('layouts.partials.batch_cutoff_banner')
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if(session()->has('iklan') && session()->get('iklan') == 0)
|
|
||||||
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 1rem; right: 1rem; width:100%;z-index:1;" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
|
|
||||||
<i class="text-danger fa-2x fa fa-exclamation-triangle mr-2"></i>
|
|
||||||
<strong class="mr-auto text-danger fa-2x">Amaran</strong>
|
|
||||||
{{-- <small>11 mins ago</small> --}}
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
<b style="font-size:18px;">sila tukar kata laluan asal dengan segera!</b>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
</script>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
<main class="py-4">
|
<main class="py-4">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -164,29 +164,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@if(session()->has('iklan') && session()->get('iklan') == 0)
|
|
||||||
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 1rem; right: 1rem; width:100%;z-index:1;" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
|
|
||||||
<i class="text-danger fa-2x fa fa-exclamation-triangle mr-2"></i>
|
|
||||||
<strong class="mr-auto text-danger fa-2x">Amaran</strong>
|
|
||||||
{{-- <small>11 mins ago</small> --}}
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
<b style="font-size:18px;">sila tukar kata laluan asal dengan segera!</b>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
</script>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<main class="py-4">
|
<main class="py-4">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -111,14 +111,17 @@
|
|||||||
<li class="nav-item dropdown" style="margin-right:10px;">
|
<li class="nav-item dropdown" style="margin-right:10px;">
|
||||||
<a id="navbarDropdown" class="nav-link " href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
<a id="navbarDropdown" class="nav-link " href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
||||||
<i id="bell" class="fa fa-bell"></i>
|
<i id="bell" class="fa fa-bell"></i>
|
||||||
|
<span id="staff-notification-badge" class="staff-notification-badge"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
<div class="dropdown-menu dropdown-menu-right staff-notification-menu" aria-labelledby="navbarDropdown">
|
||||||
<div id="divbiasa">
|
<div id="divbiasa" class="d-none">
|
||||||
<a class="dropdown-item" id="gadailinkz" href="#">
|
<a class="dropdown-item" id="gadailinkz" href="#">
|
||||||
Tiada Notifikasi
|
Tiada Notifikasi
|
||||||
</a>
|
</a>
|
||||||
|
<a class="dropdown-item" id="linkz" href="#"></a>
|
||||||
</div>
|
</div>
|
||||||
|
@include('layouts.partials.notification_inbox')
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -254,29 +257,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@if(session()->has('iklan') && session()->get('iklan') == 0)
|
|
||||||
|
|
||||||
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="position: absolute; top: 1rem; right: 1rem; width:100%;z-index:1;" data-autohide="false">
|
|
||||||
<div class="toast-header">
|
|
||||||
|
|
||||||
<i class="text-danger fa-2x fa fa-exclamation-triangle mr-2"></i>
|
|
||||||
<strong class="mr-auto text-danger fa-2x">Amaran</strong>
|
|
||||||
{{-- <small>11 mins ago</small> --}}
|
|
||||||
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toast-body">
|
|
||||||
<b style="font-size:18px;">sila tukar kata laluan asal dengan segera!</b>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$('.toast').toast('show');
|
|
||||||
</script>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<main class="py-4">
|
<main class="py-4">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -0,0 +1,355 @@
|
|||||||
|
<style>
|
||||||
|
#batch-cutoff-banner {
|
||||||
|
position: fixed;
|
||||||
|
top: 112px;
|
||||||
|
right: 24px;
|
||||||
|
z-index: 1080;
|
||||||
|
width: min(380px, calc(100vw - 32px));
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: #fff;
|
||||||
|
background: #b91c1c;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 18px 40px rgba(127, 29, 29, 0.35);
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner.batch-cutoff-warn {
|
||||||
|
background: #db2777;
|
||||||
|
box-shadow: 0 18px 40px rgba(190, 24, 93, 0.32);
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner.batch-cutoff-warn .batch-cutoff-link {
|
||||||
|
color: #9d174d !important;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner.batch-cutoff-urgent {
|
||||||
|
background: #991b1b;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-inner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 14px 16px 16px;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-copy {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 999px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(255, 255, 255, 0.14);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-sub {
|
||||||
|
display: block;
|
||||||
|
margin-top: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: rgba(255, 255, 255, 0.82);
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding-left: 48px;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 64px;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(0, 0, 0, 0.22);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-link,
|
||||||
|
#batch-cutoff-banner .batch-cutoff-notify {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 7px 14px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-decoration: none !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-link {
|
||||||
|
flex: 1;
|
||||||
|
color: #991b1b !important;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-link:hover {
|
||||||
|
color: #7f1d1d !important;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-notify {
|
||||||
|
color: #fff !important;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.55);
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-notify:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
#batch-cutoff-banner {
|
||||||
|
top: auto;
|
||||||
|
bottom: 16px;
|
||||||
|
right: 16px;
|
||||||
|
left: 16px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
#batch-cutoff-banner .batch-cutoff-actions {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="batch-cutoff-banner" class="d-none" role="alert">
|
||||||
|
<div class="batch-cutoff-inner">
|
||||||
|
<div class="batch-cutoff-copy">
|
||||||
|
<span class="batch-cutoff-icon" aria-hidden="true"><i class="fas fa-clock"></i></span>
|
||||||
|
<div>
|
||||||
|
<span id="batch-cutoff-title" class="batch-cutoff-title">Hantar senarai pembiayaan online</span>
|
||||||
|
<span id="batch-cutoff-body" class="batch-cutoff-sub"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="batch-cutoff-actions">
|
||||||
|
<span id="batch-cutoff-countdown" class="batch-cutoff-chip">00:00</span>
|
||||||
|
<a id="batch-cutoff-link" href="{{ route('pembiayaan.online.pc') }}" class="batch-cutoff-link">Buka senarai</a>
|
||||||
|
<button type="button" id="batch-cutoff-enable-notify" class="batch-cutoff-notify d-none">Benarkan notifikasi</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var STATUS_URL = @json(route('pembiayaan.online.pc.reminder'));
|
||||||
|
var POLL_MS = 60000;
|
||||||
|
var TICK_MS = 1000;
|
||||||
|
var state = null;
|
||||||
|
var fetchedAt = 0;
|
||||||
|
var serverNowAtFetch = 0;
|
||||||
|
var banner = document.getElementById('batch-cutoff-banner');
|
||||||
|
var titleEl = document.getElementById('batch-cutoff-title');
|
||||||
|
var bodyEl = document.getElementById('batch-cutoff-body');
|
||||||
|
var linkEl = document.getElementById('batch-cutoff-link');
|
||||||
|
var enableBtn = document.getElementById('batch-cutoff-enable-notify');
|
||||||
|
var countdownEl = document.getElementById('batch-cutoff-countdown');
|
||||||
|
|
||||||
|
if (!banner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function todayKey() {
|
||||||
|
var d = new Date();
|
||||||
|
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
function pad(n) {
|
||||||
|
return n < 10 ? '0' + n : String(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function storageKey(kind, level) {
|
||||||
|
var slot = (state && state.slot) ? state.slot : 'BATCH';
|
||||||
|
return 'batchCutoff:' + kind + ':' + slot + ':' + todayKey() + ':' + level;
|
||||||
|
}
|
||||||
|
|
||||||
|
function was(kind, level) {
|
||||||
|
try {
|
||||||
|
return sessionStorage.getItem(storageKey(kind, level)) === '1';
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mark(kind, level) {
|
||||||
|
try {
|
||||||
|
sessionStorage.setItem(storageKey(kind, level), '1');
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remainingMs() {
|
||||||
|
if (!state) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var cutoffAt = state.cutoff_at ? Date.parse(state.cutoff_at) : NaN;
|
||||||
|
if (!isFinite(cutoffAt)) {
|
||||||
|
var parts = String(state.cutoff || '').split(':');
|
||||||
|
if (parts.length < 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var now = new Date();
|
||||||
|
cutoffAt = new Date(now.getFullYear(), now.getMonth(), now.getDate(), parseInt(parts[0], 10), parseInt(parts[1], 10), 0).getTime();
|
||||||
|
}
|
||||||
|
var elapsed = Date.now() - fetchedAt;
|
||||||
|
var nowMs = (serverNowAtFetch || Date.now()) + elapsed;
|
||||||
|
return cutoffAt - nowMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canNotify() {
|
||||||
|
return typeof Notification !== 'undefined' && Notification.permission === 'granted';
|
||||||
|
}
|
||||||
|
|
||||||
|
function notifyDefault() {
|
||||||
|
return typeof Notification !== 'undefined' && Notification.permission === 'default';
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendBrowserNotification(level, title, body) {
|
||||||
|
if (!canNotify() || was('notify', level)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mark('notify', level);
|
||||||
|
try {
|
||||||
|
var n = new Notification(title, {
|
||||||
|
body: body,
|
||||||
|
tag: 'batch-cutoff-' + ((state && state.slot) || '') + '-' + level,
|
||||||
|
requireInteraction: level === 1
|
||||||
|
});
|
||||||
|
n.onclick = function () {
|
||||||
|
window.focus();
|
||||||
|
if (state && state.url) {
|
||||||
|
window.location.href = state.url;
|
||||||
|
}
|
||||||
|
n.close();
|
||||||
|
};
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideBanner() {
|
||||||
|
banner.classList.add('d-none');
|
||||||
|
banner.classList.remove('batch-cutoff-urgent', 'batch-cutoff-warn');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showBanner(level, remaining) {
|
||||||
|
var mins = Math.max(0, Math.floor(remaining / 60000));
|
||||||
|
var secs = Math.max(0, Math.floor((remaining % 60000) / 1000));
|
||||||
|
var slot = (state && state.slot) ? state.slot : 'Batch';
|
||||||
|
var cutoff = (state && state.cutoff) ? state.cutoff : '';
|
||||||
|
var count = (state && state.bilangan) ? state.bilangan : 0;
|
||||||
|
var countdown = pad(mins) + ':' + pad(secs);
|
||||||
|
if (countdownEl) {
|
||||||
|
countdownEl.textContent = countdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level === 1) {
|
||||||
|
titleEl.textContent = 'Sila hantar senarai pembiayaan online sekarang!! 😡 😡';
|
||||||
|
bodyEl.textContent = slot + ' ditutup pada ' + cutoff + ' · ' + count + ' rekod belum dihantar';
|
||||||
|
banner.classList.add('batch-cutoff-urgent');
|
||||||
|
banner.classList.remove('batch-cutoff-warn');
|
||||||
|
} else {
|
||||||
|
titleEl.textContent = 'Sila hantar senarai pembiayaan online 😇 😇';
|
||||||
|
bodyEl.textContent = slot + ' ditutup pada ' + cutoff + ' · ' + count + ' rekod menunggu';
|
||||||
|
banner.classList.add('batch-cutoff-warn');
|
||||||
|
banner.classList.remove('batch-cutoff-urgent');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state && state.url) {
|
||||||
|
linkEl.href = state.url;
|
||||||
|
}
|
||||||
|
if (notifyDefault()) {
|
||||||
|
enableBtn.classList.remove('d-none');
|
||||||
|
} else {
|
||||||
|
enableBtn.classList.add('d-none');
|
||||||
|
}
|
||||||
|
banner.classList.remove('d-none');
|
||||||
|
}
|
||||||
|
|
||||||
|
function tick() {
|
||||||
|
if (!state || !state.enabled || state.ditutup || state.lewat || !state.bilangan) {
|
||||||
|
hideBanner();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var remaining = remainingMs();
|
||||||
|
if (remaining === null || remaining <= 0) {
|
||||||
|
hideBanner();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var remindMs = (state.remind_minutes || 10) * 60000;
|
||||||
|
var lastMs = (state.last_minute || 1) * 60000;
|
||||||
|
if (remaining > remindMs) {
|
||||||
|
hideBanner();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var level = remaining <= lastMs ? 1 : 10;
|
||||||
|
showBanner(level, remaining);
|
||||||
|
sendBrowserNotification(
|
||||||
|
level,
|
||||||
|
level === 1 ? '1 minit lagi: hantar senarai batch' : 'Hantar senarai pembiayaan online',
|
||||||
|
(state.slot || 'Batch') + ' tamat ' + (state.cutoff || '') + '. ' + state.bilangan + ' rekod belum dihantar.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyStatus(data) {
|
||||||
|
if (!data || !data.enabled) {
|
||||||
|
state = null;
|
||||||
|
hideBanner();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = data;
|
||||||
|
fetchedAt = Date.now();
|
||||||
|
serverNowAtFetch = data.server_now ? Date.parse(data.server_now) : Date.now();
|
||||||
|
if (!isFinite(serverNowAtFetch)) {
|
||||||
|
serverNowAtFetch = Date.now();
|
||||||
|
}
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchStatus() {
|
||||||
|
fetch(STATUS_URL, {
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' }
|
||||||
|
}).then(function (res) {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('reminder status ' + res.status);
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
}).then(applyStatus).catch(function () {});
|
||||||
|
}
|
||||||
|
|
||||||
|
enableBtn.addEventListener('click', function () {
|
||||||
|
if (typeof Notification === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Notification.requestPermission().then(function () {
|
||||||
|
if (canNotify()) {
|
||||||
|
enableBtn.classList.add('d-none');
|
||||||
|
var remaining = remainingMs();
|
||||||
|
var lastMs = ((state && state.last_minute) || 1) * 60000;
|
||||||
|
var level = remaining !== null && remaining <= lastMs ? 1 : 10;
|
||||||
|
try { sessionStorage.removeItem(storageKey('notify', level)); } catch (e) {}
|
||||||
|
tick();
|
||||||
|
} else {
|
||||||
|
enableBtn.classList.add('d-none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchStatus();
|
||||||
|
setInterval(fetchStatus, POLL_MS);
|
||||||
|
setInterval(tick, TICK_MS);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
<style>
|
||||||
|
.staff-notification-menu {
|
||||||
|
min-width: 340px;
|
||||||
|
max-width: 380px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.staff-notification-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.staff-notification-header button {
|
||||||
|
border: 0;
|
||||||
|
background: none;
|
||||||
|
color: #1abc9c;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.staff-notification-header button:disabled {
|
||||||
|
color: #bbb;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.staff-notification-list {
|
||||||
|
max-height: 360px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.staff-notification-item {
|
||||||
|
display: block;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-bottom: 1px solid #f3f3f3;
|
||||||
|
white-space: normal;
|
||||||
|
color: #333;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.staff-notification-item:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.staff-notification-item.is-unread {
|
||||||
|
background: #eafaf6;
|
||||||
|
}
|
||||||
|
.staff-notification-item .sn-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
.staff-notification-item.is-unread .sn-title {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.staff-notification-item .sn-body,
|
||||||
|
.staff-notification-item .sn-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.staff-notification-empty {
|
||||||
|
padding: 18px 14px;
|
||||||
|
text-align: center;
|
||||||
|
color: #888;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.staff-notification-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
right: 0;
|
||||||
|
font-size: 10px;
|
||||||
|
min-width: 16px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #e74c3c;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 1.2;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.staff-notification-toggle {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
a.nav-link #staff-notification-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
right: -4px;
|
||||||
|
}
|
||||||
|
li.nav-item.dropdown > a.nav-link {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="staff-notification-inbox">
|
||||||
|
<div class="staff-notification-header">
|
||||||
|
<span>Notifikasi</span>
|
||||||
|
<button type="button" id="staff-notification-mark-all" disabled>Tanda semua dibaca</button>
|
||||||
|
</div>
|
||||||
|
<div id="staff-notification-list" class="staff-notification-list">
|
||||||
|
<div class="staff-notification-empty">Memuatkan...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var listUrl = @json(route('notifications.index'));
|
||||||
|
var markAllUrl = @json(route('notifications.read.all'));
|
||||||
|
var markOneUrlTemplate = @json(url('/notifications/__ID__/read'));
|
||||||
|
var csrf = document.querySelector('meta[name="csrf-token"]');
|
||||||
|
var csrfToken = csrf ? csrf.getAttribute('content') : '';
|
||||||
|
|
||||||
|
function markOneUrl(id) {
|
||||||
|
return markOneUrlTemplate.replace('__ID__', id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return String(value == null ? '' : value)
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBadge(count) {
|
||||||
|
var badge = document.getElementById('staff-notification-badge');
|
||||||
|
var bell = document.getElementById('bell');
|
||||||
|
if (!badge) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
badge.style.display = 'inline-block';
|
||||||
|
badge.textContent = count > 99 ? '99+' : String(count);
|
||||||
|
if (bell) {
|
||||||
|
bell.style.color = '#e74c3c';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
badge.style.display = 'none';
|
||||||
|
badge.textContent = '';
|
||||||
|
if (bell) {
|
||||||
|
bell.style.color = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var markAll = document.getElementById('staff-notification-mark-all');
|
||||||
|
if (markAll) {
|
||||||
|
markAll.disabled = count < 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(payload) {
|
||||||
|
var wrap = document.getElementById('staff-notification-list');
|
||||||
|
if (!wrap) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var items = payload.notifications || [];
|
||||||
|
setBadge(payload.unread_count || 0);
|
||||||
|
|
||||||
|
if (!items.length) {
|
||||||
|
wrap.innerHTML = '<div class="staff-notification-empty">Tiada notifikasi</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap.innerHTML = items.map(function (item) {
|
||||||
|
var unread = !item.read_at;
|
||||||
|
return (
|
||||||
|
'<a class="dropdown-item staff-notification-item' + (unread ? ' is-unread' : '') + '" href="' + escapeHtml(item.url || '#') + '" data-id="' + item.id + '">' +
|
||||||
|
'<div class="sn-title">' + escapeHtml(item.title) + '</div>' +
|
||||||
|
(item.body ? '<p class="sn-body">' + escapeHtml(item.body) + '</p>' : '') +
|
||||||
|
'<p class="sn-time">' + escapeHtml(item.created_at_human || '') + '</p>' +
|
||||||
|
'</a>'
|
||||||
|
);
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadInbox() {
|
||||||
|
return fetch(listUrl, {
|
||||||
|
headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
|
||||||
|
credentials: 'same-origin'
|
||||||
|
}).then(function (res) {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Gagal muat notifikasi');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
}).then(render).catch(function () {
|
||||||
|
var wrap = document.getElementById('staff-notification-list');
|
||||||
|
if (wrap) {
|
||||||
|
wrap.innerHTML = '<div class="staff-notification-empty">Tidak dapat memuatkan notifikasi</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function postJson(url) {
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
'X-CSRF-TOKEN': csrfToken
|
||||||
|
},
|
||||||
|
credentials: 'same-origin',
|
||||||
|
body: '{}'
|
||||||
|
}).then(function (res) {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Gagal kemaskini notifikasi');
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('click', function (event) {
|
||||||
|
var target = event.target;
|
||||||
|
if (target && target.nodeType !== 1) {
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
if (!target || !target.closest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var item = target.closest('.staff-notification-item');
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var id = item.getAttribute('data-id');
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
postJson(markOneUrl(id)).catch(function () {});
|
||||||
|
});
|
||||||
|
|
||||||
|
var markAll = document.getElementById('staff-notification-mark-all');
|
||||||
|
if (markAll) {
|
||||||
|
markAll.addEventListener('click', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
postJson(markAllUrl).then(function () {
|
||||||
|
loadInbox();
|
||||||
|
}).catch(function () {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadInbox();
|
||||||
|
setInterval(loadInbox, 30000);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@@ -13,56 +13,95 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="card-body text-center">
|
<div class="card-body">
|
||||||
|
<div class="row mb-3 align-items-end">
|
||||||
<div class="row mb-4">
|
<div class="col-md-3">
|
||||||
<div class="col-2 justify-content-start">
|
<label for="date_from">Tarikh Dari</label>
|
||||||
|
<input type="date" id="date_from" class="form-control" value="{{ $dateFrom }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8 mt-3 justify-content-center">
|
<div class="col-md-3">
|
||||||
|
<label for="date_to">Tarikh Hingga</label>
|
||||||
|
<input type="date" id="date_to" class="form-control" value="{{ $dateTo }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-2">
|
<div class="col-md-3">
|
||||||
|
<button type="button" id="btn-filter-rekod" class="btn btn-primary mt-3 mt-md-0">Cari</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class='table table-striped table-hover' id='table-kelulusan' style="width:100%;">
|
<x-datatable
|
||||||
<thead class="thead-dark">
|
id="table-kelulusan"
|
||||||
<tr>
|
filename="Rekod_Lulus_Operasi"
|
||||||
<th>No Rujukan</th>
|
class="text-center"
|
||||||
<th>Status</th>
|
:columns="['Tarikh', 'No Rujukan', 'Status', 'Komen', 'Nilai Pembiayaan', 'Nilai Marhun', 'Berat', 'Margin', 'Pelulus']"
|
||||||
<th>Komen</th>
|
/>
|
||||||
<th>Nilai Pembiayaan</th>
|
|
||||||
<th>Nilai Marhun</th>
|
|
||||||
<th>Berat</th>
|
|
||||||
<th>Margin</th>
|
|
||||||
<th>Pelulus</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach($arraykelulusan as $index=>$k)
|
|
||||||
<tr>
|
|
||||||
<td>{{ $k['norujukan'] }}</td>
|
|
||||||
<td>{{ $k['status'] }}</td>
|
|
||||||
<td>{{ $k['komen'] }}</td>
|
|
||||||
<td>{{ $k['pinjaman'] }}</td>
|
|
||||||
<td>{{ $k['nilaimarhun'] }}</td>
|
|
||||||
<td>{{ $k['berat'] }}</td>
|
|
||||||
<td>{{ $k['margin'] }}</td>
|
|
||||||
<td>{{ $k['pelulus'] }}</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return $('<div>').text(value == null ? '' : String(value)).html();
|
||||||
|
}
|
||||||
|
|
||||||
var tablekelulusan = $('#table-kelulusan').DataTable({
|
var tablekelulusan = initErahnDatatable('#table-kelulusan', {
|
||||||
"scrollX": true
|
deferRender: true,
|
||||||
|
order: [[0, 'desc']],
|
||||||
|
language: {
|
||||||
|
emptyTable: 'Tiada rekod',
|
||||||
|
zeroRecords: 'Tiada rekod dijumpai'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setLoading(isLoading) {
|
||||||
|
$('#btn-filter-rekod').prop('disabled', isLoading).text(isLoading ? 'Memuatkan...' : 'Cari');
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadRekodLulus() {
|
||||||
|
var dateFrom = $('#date_from').val();
|
||||||
|
var dateTo = $('#date_to').val();
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
tablekelulusan.clear().draw();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('operasi.rekodlepas.data') }}",
|
||||||
|
method: 'GET',
|
||||||
|
data: {
|
||||||
|
date_from: dateFrom,
|
||||||
|
date_to: dateTo
|
||||||
|
},
|
||||||
|
success: function (response) {
|
||||||
|
var rows = response.data || [];
|
||||||
|
var data = rows.map(function (row) {
|
||||||
|
return [
|
||||||
|
escapeHtml(row.tarikh || '-'),
|
||||||
|
escapeHtml(row.norujukan || '-'),
|
||||||
|
escapeHtml(row.status || '-'),
|
||||||
|
escapeHtml(row.komen || '-'),
|
||||||
|
escapeHtml(row.pinjaman || '-'),
|
||||||
|
escapeHtml(row.nilaimarhun || '-'),
|
||||||
|
escapeHtml(row.berat || '-'),
|
||||||
|
escapeHtml(row.margin || '-'),
|
||||||
|
escapeHtml(row.pelulus || '-')
|
||||||
|
];
|
||||||
|
});
|
||||||
|
tablekelulusan.rows.add(data).draw();
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Ralat',
|
||||||
|
text: 'Gagal memuatkan rekod lulus.'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#btn-filter-rekod').on('click', loadRekodLulus);
|
||||||
|
loadRekodLulus();
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -54,104 +54,131 @@
|
|||||||
@if($pendingCount > 0)
|
@if($pendingCount > 0)
|
||||||
<form method="post"
|
<form method="post"
|
||||||
action="{{ route('pembiayaan.online.operasi.approve.batch', ['kodcaw' => $kodcaw, 'batchId' => $batch['id']]) }}"
|
action="{{ route('pembiayaan.online.operasi.approve.batch', ['kodcaw' => $kodcaw, 'batchId' => $batch['id']]) }}"
|
||||||
class="d-inline"
|
class="d-inline js-swal-confirm"
|
||||||
onsubmit="return confirm('Luluskan semua {{ $pendingCount }} rekod menunggu dalam batch ini?');">
|
data-title="Lulus Semua Menunggu?"
|
||||||
|
data-html="Luluskan semua <b>{{ $pendingCount }}</b> rekod menunggu dalam batch <b>{{ $batch['batch_no'] ?? '-' }}</b>?"
|
||||||
|
data-confirm="Ya, Lulus Semua">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit" class="btn btn-success btn-sm">Lulus Semua Menunggu ({{ $pendingCount }})</button>
|
<button type="submit" class="btn btn-success btn-sm">Lulus Semua Menunggu ({{ $pendingCount }})</button>
|
||||||
</form>
|
</form>
|
||||||
@endif
|
@endif
|
||||||
@if($approvedCount > 0)
|
@if($approvedCount > 0)
|
||||||
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#paidBatchModal">
|
<button type="button" class="btn btn-dark btn-sm" data-toggle="modal" data-target="#paidBatchModal">
|
||||||
Tanda PAID Batch ({{ $approvedCount }})
|
Tanda semua sebagai dibayar ({{ $approvedCount }})
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body table-responsive">
|
<div class="card-body">
|
||||||
<table class="table table-striped table-sm text-center">
|
<x-datatable
|
||||||
<thead class="thead-dark">
|
id="batch_lines"
|
||||||
|
class="table-sm text-center"
|
||||||
|
:filename="'Batch_' . ($batch['batch_no'] ?? $batch['id'])"
|
||||||
|
:columns="['Bil', 'Status', 'SAG', 'Pelanggan', 'No KP', 'Bank', 'No Akaun', 'Nama Akaun', 'Pinjaman (RM)', 'Rujukan Bayaran', 'Dokumen', 'Tindakan']"
|
||||||
|
:skipExport="['Dokumen', 'Tindakan']"
|
||||||
|
>
|
||||||
|
@foreach($lines as $line)
|
||||||
|
@php
|
||||||
|
$st = $line['status'] ?? '';
|
||||||
|
$badge = 'badge-secondary';
|
||||||
|
if ($st === 'APPROVED') $badge = 'badge-success';
|
||||||
|
elseif ($st === 'PAID') $badge = 'badge-dark';
|
||||||
|
elseif ($st === 'REJECTED_PC') $badge = 'badge-danger';
|
||||||
|
elseif (in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true)) $badge = 'badge-primary';
|
||||||
|
@endphp
|
||||||
<tr>
|
<tr>
|
||||||
<th>Status</th>
|
<td>{{ $loop->iteration }}</td>
|
||||||
<th>SAG</th>
|
<td><span class="badge {{ $badge }}">{{ $st ?: '-' }}</span></td>
|
||||||
<th>Pelanggan</th>
|
<td>{{ $line['norujukan'] ?? '-' }}</td>
|
||||||
<th>No KP</th>
|
<td class="text-left">{{ $line['nama_pelanggan'] ?? '-' }}</td>
|
||||||
<th>Bank</th>
|
<td>{{ $line['nokp'] ?? '-' }}</td>
|
||||||
<th>No Akaun</th>
|
<td>{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}</td>
|
||||||
<th>Nama Akaun</th>
|
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
||||||
<th>Pinjaman (RM)</th>
|
<td class="text-left">{{ $line['nama_akaun'] ?? '-' }}</td>
|
||||||
<th>Rujukan Bayaran</th>
|
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
||||||
<th>Tindakan</th>
|
<td>{{ $line['no_rujukan_bayaran'] ?? '-' }}</td>
|
||||||
|
<td class="text-nowrap">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-dark btn-preview-sag"
|
||||||
|
data-url="{{ route('pembiayaan.online.operasi.sag', ['kodcaw' => $kodcaw, 'id' => $line['id']]) }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
SAG
|
||||||
|
</button>
|
||||||
|
@if(!empty($line['bukti_akaun_file_id']))
|
||||||
|
<a class="btn btn-sm btn-outline-primary"
|
||||||
|
href="{{ route('pembiayaan.online.operasi.bukti.akaun', ['kodcaw' => $kodcaw, 'id' => $line['id']]) }}"
|
||||||
|
target="_blank">
|
||||||
|
Slip Bank
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<span class="text-muted small">Tiada slip</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td class="text-nowrap">
|
||||||
|
@if(in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true))
|
||||||
|
<form method="post"
|
||||||
|
action="{{ route('pembiayaan.online.operasi.approve', ['kodcaw' => $kodcaw, 'id' => $line['id']]) }}"
|
||||||
|
class="d-inline js-swal-confirm"
|
||||||
|
data-title="Luluskan Rekod?"
|
||||||
|
data-html="Luluskan rekod <b>{{ $line['norujukan'] ?? '-' }}</b>?"
|
||||||
|
data-confirm="Ya, Lulus">
|
||||||
|
@csrf
|
||||||
|
<input type="hidden" name="batch_id" value="{{ $batch['id'] }}">
|
||||||
|
<button type="submit" class="btn btn-success btn-sm">Lulus</button>
|
||||||
|
</form>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-danger btn-sm btn-reject"
|
||||||
|
data-id="{{ $line['id'] }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
Tolak
|
||||||
|
</button>
|
||||||
|
@elseif($st === 'APPROVED')
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-dark btn-sm btn-paid"
|
||||||
|
data-id="{{ $line['id'] }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
Tanda sebagai dibayar
|
||||||
|
</button>
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-outline-danger btn-sm btn-reject"
|
||||||
|
data-id="{{ $line['id'] }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
Tolak
|
||||||
|
</button>
|
||||||
|
@elseif($st === 'PAID')
|
||||||
|
<span class="text-muted small">Selesai</span>
|
||||||
|
@else
|
||||||
|
<span class="text-muted small">-</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
@endforeach
|
||||||
<tbody>
|
</x-datatable>
|
||||||
@forelse($lines as $line)
|
|
||||||
@php
|
|
||||||
$st = $line['status'] ?? '';
|
|
||||||
$badge = 'badge-secondary';
|
|
||||||
if ($st === 'APPROVED') $badge = 'badge-success';
|
|
||||||
elseif ($st === 'PAID') $badge = 'badge-dark';
|
|
||||||
elseif ($st === 'REJECTED_PC') $badge = 'badge-danger';
|
|
||||||
elseif (in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true)) $badge = 'badge-primary';
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<td><span class="badge {{ $badge }}">{{ $st ?: '-' }}</span></td>
|
|
||||||
<td>{{ $line['norujukan'] ?? '-' }}</td>
|
|
||||||
<td class="text-left">{{ $line['nama_pelanggan'] ?? '-' }}</td>
|
|
||||||
<td>{{ $line['nokp'] ?? '-' }}</td>
|
|
||||||
<td>{{ $line['nama_bank'] ?? $line['kodbank'] ?? '-' }}</td>
|
|
||||||
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
|
||||||
<td class="text-left">{{ $line['nama_akaun'] ?? '-' }}</td>
|
|
||||||
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
|
||||||
<td>{{ $line['no_rujukan_bayaran'] ?? '-' }}</td>
|
|
||||||
<td class="text-nowrap">
|
|
||||||
@if(in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true))
|
|
||||||
<form method="post"
|
|
||||||
action="{{ route('pembiayaan.online.operasi.approve', ['kodcaw' => $kodcaw, 'id' => $line['id']]) }}"
|
|
||||||
class="d-inline"
|
|
||||||
onsubmit="return confirm('Luluskan rekod {{ $line['norujukan'] ?? '' }}?');">
|
|
||||||
@csrf
|
|
||||||
<input type="hidden" name="batch_id" value="{{ $batch['id'] }}">
|
|
||||||
<button type="submit" class="btn btn-success btn-sm">Lulus</button>
|
|
||||||
</form>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-danger btn-sm btn-reject"
|
|
||||||
data-id="{{ $line['id'] }}"
|
|
||||||
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
|
||||||
Tolak
|
|
||||||
</button>
|
|
||||||
@elseif($st === 'APPROVED')
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-dark btn-sm btn-paid"
|
|
||||||
data-id="{{ $line['id'] }}"
|
|
||||||
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
|
||||||
PAID + Bukti
|
|
||||||
</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-outline-danger btn-sm btn-reject"
|
|
||||||
data-id="{{ $line['id'] }}"
|
|
||||||
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
|
||||||
Tolak
|
|
||||||
</button>
|
|
||||||
@elseif($st === 'PAID')
|
|
||||||
<span class="text-muted small">Selesai</span>
|
|
||||||
@else
|
|
||||||
<span class="text-muted small">-</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@empty
|
|
||||||
<tr>
|
|
||||||
<td colspan="10">Tiada rekod dalam batch.</td>
|
|
||||||
</tr>
|
|
||||||
@endforelse
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{-- SAG preview modal --}}
|
||||||
|
<div class="modal fade" id="sagPreviewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl" role="document" style="max-width:1140px;">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Pratonton SAG — <span id="sagPreviewTitle"></span></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body p-2">
|
||||||
|
<iframe id="sagPreviewFrame" title="Pratonton SAG" src="about:blank"
|
||||||
|
style="width:100%;height:75vh;border:1px solid #dee2e6;background:#f8f9fa;"></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{-- Reject modal --}}
|
{{-- Reject modal --}}
|
||||||
<div class="modal fade" id="rejectModal" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="modal fade" id="rejectModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
@@ -188,7 +215,7 @@
|
|||||||
<input type="hidden" name="batch_id" value="{{ $batch['id'] }}">
|
<input type="hidden" name="batch_id" value="{{ $batch['id'] }}">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Tanda PAID — <span id="paidNorujukan"></span></h5>
|
<h5 class="modal-title">Tanda sebagai dibayar — <span id="paidNorujukan"></span></h5>
|
||||||
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
@@ -203,12 +230,12 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Bukti Bayaran <span class="text-danger">*</span></label>
|
<label>Bukti Bayaran <span class="text-danger">*</span></label>
|
||||||
<input type="file" name="bukti" class="form-control-file" accept=".pdf,.jpg,.jpeg,.png,.gif" required>
|
<input type="file" name="bukti" class="form-control-file" accept=".pdf,.jpg,.jpeg,.png,.gif" required>
|
||||||
<small class="text-muted">PDF / imej slip pindahan bank</small>
|
<small class="text-muted">PDF / imej slip bank</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
|
||||||
<button type="submit" class="btn btn-dark">Simpan PAID</button>
|
<button type="submit" class="btn btn-dark">Simpan</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -224,7 +251,7 @@
|
|||||||
@csrf
|
@csrf
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Tanda PAID Semua APPROVED ({{ $approvedCount }})</h5>
|
<h5 class="modal-title">Tanda semua sebagai dibayar ({{ $approvedCount }})</h5>
|
||||||
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
@@ -244,7 +271,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
|
||||||
<button type="submit" class="btn btn-dark">Simpan PAID Batch</button>
|
<button type="submit" class="btn btn-dark">Simpan</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -252,7 +279,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$('.btn-reject').on('click', function () {
|
var table = initErahnDatatable('#batch_lines', {
|
||||||
|
columnDefs: [
|
||||||
|
{ targets: 0, orderable: false, searchable: false, width: '40px' },
|
||||||
|
{ targets: [10, 11], orderable: false, searchable: false }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
table.on('draw.dt', function () {
|
||||||
|
table.column(0, { search: 'applied', order: 'applied' }).nodes().each(function (cell, i) {
|
||||||
|
cell.innerHTML = i + 1;
|
||||||
|
});
|
||||||
|
}).draw();
|
||||||
|
|
||||||
|
$('#batch_lines').on('click', '.btn-preview-sag', function () {
|
||||||
|
$('#sagPreviewTitle').text($(this).data('norujukan') || '');
|
||||||
|
$('#sagPreviewFrame').attr('src', $(this).data('url'));
|
||||||
|
$('#sagPreviewModal').modal('show');
|
||||||
|
});
|
||||||
|
$('#sagPreviewModal').on('hidden.bs.modal', function () {
|
||||||
|
$('#sagPreviewFrame').attr('src', 'about:blank');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#batch_lines').on('click', '.btn-reject', function () {
|
||||||
var id = $(this).data('id');
|
var id = $(this).data('id');
|
||||||
$('#rejectForm').attr(
|
$('#rejectForm').attr(
|
||||||
'action',
|
'action',
|
||||||
@@ -263,7 +311,7 @@
|
|||||||
$('#rejectModal').modal('show');
|
$('#rejectModal').modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-paid').on('click', function () {
|
$('#batch_lines').on('click', '.btn-paid', function () {
|
||||||
var id = $(this).data('id');
|
var id = $(this).data('id');
|
||||||
$('#paidForm').attr(
|
$('#paidForm').attr(
|
||||||
'action',
|
'action',
|
||||||
@@ -272,5 +320,25 @@
|
|||||||
$('#paidNorujukan').text($(this).data('norujukan'));
|
$('#paidNorujukan').text($(this).data('norujukan'));
|
||||||
$('#paidModal').modal('show');
|
$('#paidModal').modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).on('submit', '.js-swal-confirm', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var form = this;
|
||||||
|
Swal.fire({
|
||||||
|
title: $(form).attr('data-title') || 'Pengesahan',
|
||||||
|
html: $(form).attr('data-html') || 'Teruskan tindakan ini?',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: $(form).attr('data-confirm') || 'Ya',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
allowOutsideClick: false
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
<th>No Akaun</th>
|
<th>No Akaun</th>
|
||||||
<th>Pinjaman (RM)</th>
|
<th>Pinjaman (RM)</th>
|
||||||
<th>Rujukan Bayaran</th>
|
<th>Rujukan Bayaran</th>
|
||||||
|
<th>Dokumen</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -53,6 +54,23 @@
|
|||||||
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
||||||
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
||||||
<td>{{ $line['no_rujukan_bayaran'] ?? '-' }}</td>
|
<td>{{ $line['no_rujukan_bayaran'] ?? '-' }}</td>
|
||||||
|
<td class="text-nowrap">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-dark btn-preview-sag"
|
||||||
|
data-url="{{ route('pembiayaan.online.pc.sag', ['id' => $line['id']]) }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
SAG
|
||||||
|
</button>
|
||||||
|
@if(!empty($line['bukti_akaun_file_id']))
|
||||||
|
<a class="btn btn-sm btn-outline-primary"
|
||||||
|
href="{{ route('pembiayaan.online.pc.bukti.akaun', ['id' => $line['id']]) }}"
|
||||||
|
target="_blank">
|
||||||
|
Slip Bank
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<span class="text-muted small">Tiada slip</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -62,4 +80,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="sagPreviewModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl" role="document" style="max-width:1140px;">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Pratonton SAG — <span id="sagPreviewTitle"></span></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body p-2">
|
||||||
|
<iframe id="sagPreviewFrame" title="Pratonton SAG" src="about:blank"
|
||||||
|
style="width:100%;height:75vh;border:1px solid #dee2e6;background:#f8f9fa;"></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('.btn-preview-sag').on('click', function () {
|
||||||
|
$('#sagPreviewTitle').text($(this).data('norujukan') || '');
|
||||||
|
$('#sagPreviewFrame').attr('src', $(this).data('url'));
|
||||||
|
$('#sagPreviewModal').modal('show');
|
||||||
|
});
|
||||||
|
$('#sagPreviewModal').on('hidden.bs.modal', function () {
|
||||||
|
$('#sagPreviewFrame').attr('src', 'about:blank');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -69,13 +69,13 @@
|
|||||||
<div class="card-header d-flex justify-content-between align-items-center flex-wrap">
|
<div class="card-header d-flex justify-content-between align-items-center flex-wrap">
|
||||||
<h5 class="mb-0">Senarai Pembiayaan Online — PAID</h5>
|
<h5 class="mb-0">Senarai Pembiayaan Online — PAID</h5>
|
||||||
<button type="button" class="btn btn-success btn-sm mt-2 mt-md-0" id="btnMarkBlast" disabled>
|
<button type="button" class="btn btn-success btn-sm mt-2 mt-md-0" id="btnMarkBlast" disabled>
|
||||||
Sahkan Tally / Selesai
|
Sahkan semua sebagai dibayar
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="small text-muted">
|
<p class="small text-muted">
|
||||||
Semak jumlah & bukti bayaran sepadan dengan pelanggan. Setelah semak, tanda selesai.
|
Semak jumlah & bukti bayaran sepadan dengan pelanggan. Setelah semak, tanda selesai.
|
||||||
(WhatsApp/SMS blast boleh disambung kemudian — butang ini menanda rekod sebagai selesai semak.)
|
WhatsApp notis (template Cloud API) akan dihantar selepas tally. Di persekitaran ujian ia pergi ke nombor admin, bukan pelanggan.
|
||||||
</p>
|
</p>
|
||||||
<form id="formMarkBlast" method="post" action="{{ route('pembiayaan.online.pc.blast') }}">
|
<form id="formMarkBlast" method="post" action="{{ route('pembiayaan.online.pc.blast') }}">
|
||||||
@csrf
|
@csrf
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
function syncBlastButton() {
|
function syncBlastButton() {
|
||||||
var n = $('.row-check:checked').length;
|
var n = $('.row-check:checked').length;
|
||||||
$('#btnMarkBlast').prop('disabled', n === 0);
|
$('#btnMarkBlast').prop('disabled', n === 0);
|
||||||
$('#btnMarkBlast').text(n ? ('Sahkan Tally / Selesai (' + n + ')') : 'Sahkan Tally / Selesai');
|
$('#btnMarkBlast').text(n ? ('Sahkan semua sebagai dibayar (' + n + ')') : 'Sahkan semua sebagai dibayar');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#checkAll').on('change', function () {
|
$('#checkAll').on('change', function () {
|
||||||
@@ -180,7 +180,7 @@
|
|||||||
|
|
||||||
$('#btnMarkBlast').on('click', function () {
|
$('#btnMarkBlast').on('click', function () {
|
||||||
if ($('.row-check:checked').length === 0) return;
|
if ($('.row-check:checked').length === 0) return;
|
||||||
if (!confirm('Sahkan tally untuk rekod dipilih? Rekod akan ditanda selesai semak/blast.')) return;
|
if (!confirm('Sahkan semua sebagai dibayar untuk rekod dipilih? Rekod akan ditanda sebagai dibayar dan WhatsApp notis akan dihantar.')) return;
|
||||||
$('#formMarkBlast').submit();
|
$('#formMarkBlast').submit();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -33,6 +33,20 @@
|
|||||||
if (is_object($pendingReq)) {
|
if (is_object($pendingReq)) {
|
||||||
$pendingReq = json_decode(json_encode($pendingReq), true);
|
$pendingReq = json_decode(json_encode($pendingReq), true);
|
||||||
}
|
}
|
||||||
|
$lineRows = collect($lines);
|
||||||
|
$verifiedCount = $lineRows->where('status', 'VERIFIED_PC')->count();
|
||||||
|
$unverifiedCount = $lineRows->count() - $verifiedCount;
|
||||||
|
$slotArr = is_array($slot) ? $slot : [];
|
||||||
|
$slotName = $slotArr['slot'] ?? 'BATCH1';
|
||||||
|
$slotCutoff = $slotArr['cutoff'] ?? '11:00';
|
||||||
|
$slotProses = $slotArr['proses'] ?? '12:30';
|
||||||
|
$slotLewat = !empty($slotArr['lewat']);
|
||||||
|
$slotJadual = $slotArr['jadual'] ?? [
|
||||||
|
['slot' => 'BATCH1', 'label' => 'Batch 1', 'mula' => '00:00', 'cutoff' => '11:00', 'proses' => '12:30'],
|
||||||
|
['slot' => 'BATCH2', 'label' => 'Batch 2', 'mula' => '11:00', 'cutoff' => '15:00', 'proses' => '16:30'],
|
||||||
|
];
|
||||||
|
$slotBakiMinit = (int) ($slotArr['baki_minit'] ?? 0);
|
||||||
|
$slotHampirTamat = !$slotLewat && $slotBakiMinit > 0 && $slotBakiMinit <= 30;
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@if($isClosed)
|
@if($isClosed)
|
||||||
@@ -56,6 +70,66 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
<div class="alert {{ $slotLewat ? 'alert-warning' : ($slotHampirTamat ? 'alert-warning' : 'alert-info') }} mb-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-start flex-wrap">
|
||||||
|
<div class="mb-2 mr-3">
|
||||||
|
<strong>Jadual Slot Batch</strong>
|
||||||
|
<div class="mt-1">
|
||||||
|
PC / PPC sila semak dan <b>hantar senarai sebelum tamat slot</b>.
|
||||||
|
Rekod yang dihantar selepas cutoff mungkin diproses pada slot atau hari berikutnya.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-2 text-md-right">
|
||||||
|
@if($slotLewat)
|
||||||
|
Slot semasa: <b>{{ $slotName }}</b> (selepas cutoff {{ $slotCutoff }})
|
||||||
|
@else
|
||||||
|
Slot semasa: <b>{{ $slotName }}</b>
|
||||||
|
· Hantar sebelum <b>{{ $slotCutoff }}</b>
|
||||||
|
<div class="small" id="slotCountdown"
|
||||||
|
data-cutoff="{{ $slotCutoff }}"
|
||||||
|
data-lewat="{{ $slotLewat ? '1' : '0' }}">
|
||||||
|
@if($slotBakiMinit > 0)
|
||||||
|
Baki masa: {{ intdiv($slotBakiMinit, 60) }}j {{ $slotBakiMinit % 60 }}m
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive mb-0">
|
||||||
|
<table class="table table-sm table-bordered mb-0 bg-white">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Slot</th>
|
||||||
|
<th>Hantar senarai sebelum</th>
|
||||||
|
<th>Proses Operasi</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach($slotJadual as $row)
|
||||||
|
@php
|
||||||
|
$rowSlot = $row['slot'] ?? '';
|
||||||
|
$isCurrent = $rowSlot === $slotName && !$slotLewat;
|
||||||
|
$isDone = $slotLewat
|
||||||
|
|| ($slotName === 'BATCH2' && $rowSlot === 'BATCH1');
|
||||||
|
@endphp
|
||||||
|
<tr class="{{ $isCurrent ? 'table-primary' : '' }}">
|
||||||
|
<td>
|
||||||
|
{{ $row['label'] ?? $rowSlot }}
|
||||||
|
@if($isCurrent)
|
||||||
|
<span class="badge badge-primary">Semasa</span>
|
||||||
|
@elseif($isDone)
|
||||||
|
<span class="badge badge-secondary">Tamat</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td>{{ $row['cutoff'] ?? '-' }}</td>
|
||||||
|
<td>~ {{ $row['proses'] ?? '-' }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -82,18 +156,30 @@
|
|||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<div class="text-muted">Queue PC</div>
|
<div class="text-muted">Senarai Pelanggan menunggu semakan</div>
|
||||||
<h4 class="mb-0">{{ count($lines) }} rekod</h4>
|
<h4 class="mb-0">{{ count($lines) }} rekod</h4>
|
||||||
<small>Jumlah RM {{ number_format((float)($queue['jumlah'] ?? 0), 2) }}</small>
|
<small>
|
||||||
|
{{ $verifiedCount }} sudah sah
|
||||||
|
/ {{ $unverifiedCount }} belum semak
|
||||||
|
· Jumlah RM {{ number_format((float)($queue['jumlah'] ?? 0), 2) }}
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="card">
|
<div class="card {{ $slotLewat || $slotHampirTamat ? 'border-warning' : '' }}">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<div class="text-muted">Slot Cadangan</div>
|
<div class="text-muted">Slot Semasa</div>
|
||||||
<h4 class="mb-0">{{ $slot['slot'] ?? '-' }}</h4>
|
<h4 class="mb-0">{{ $slotName }}</h4>
|
||||||
<small>{{ $slot['nota'] ?? '' }}</small>
|
<small>
|
||||||
|
@if($slotLewat)
|
||||||
|
Cutoff {{ $slotCutoff }} sudah tamat<br>
|
||||||
|
Masih boleh hantar; proses mungkin esok
|
||||||
|
@else
|
||||||
|
Hantar sebelum <b>{{ $slotCutoff }}</b>
|
||||||
|
· Proses ~{{ $slotProses }}
|
||||||
|
@endif
|
||||||
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,18 +187,27 @@
|
|||||||
|
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<h5 class="mb-0">Senarai Menunggu (PENDING / REJECTED)</h5>
|
<h5 class="mb-0">Senarai Menunggu (PENDING / REJECTED / SAH)</h5>
|
||||||
<button type="button" class="btn btn-primary" id="btnSubmitBatch" disabled>Hantar Batch ke Operasi</button>
|
<button type="button" class="btn btn-primary" id="btnSubmitBatch" disabled>Hantar Batch ke Operasi</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<p class="small text-muted">
|
||||||
|
Semak setiap rekod <b>satu-satu</b> (maklumat pelanggan, bank, amaun).
|
||||||
|
Hanya rekod berstatus <span class="badge badge-success">SAH</span> boleh dipilih dan dihantar ke Operasi.
|
||||||
|
@if($slotLewat)
|
||||||
|
Cutoff {{ $slotName }} ({{ $slotCutoff }}) sudah tamat — hantar sekarang jika perlu; Operasi mungkin proses esok.
|
||||||
|
@else
|
||||||
|
Sila hantar senarai <b>{{ $slotName }}</b> sebelum <b>{{ $slotCutoff }}</b>.
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
<form id="formSubmitBatch" method="post" action="{{ route('pembiayaan.online.pc.submit') }}">
|
<form id="formSubmitBatch" method="post" action="{{ route('pembiayaan.online.pc.submit') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="slot" value="{{ $slot['slot'] ?? 'BATCH1' }}">
|
<input type="hidden" name="slot" value="{{ $slotName }}">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover table-sm text-center" id="queueTable">
|
<table class="table table-striped table-hover table-sm text-center" id="queueTable">
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th><input type="checkbox" id="checkAll"></th>
|
<th><input type="checkbox" id="checkAll" title="Pilih semua yang sudah sah"></th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>SAG</th>
|
<th>SAG</th>
|
||||||
<th>Pelanggan</th>
|
<th>Pelanggan</th>
|
||||||
@@ -126,15 +221,31 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@forelse($lines as $line)
|
@forelse($lines as $line)
|
||||||
<tr class="{{ ($line['status'] ?? '') === 'REJECTED_PC' ? 'table-warning' : '' }}">
|
@php
|
||||||
|
$st = $line['status'] ?? '';
|
||||||
|
$isVerified = $st === 'VERIFIED_PC';
|
||||||
|
$isRejected = $st === 'REJECTED_PC';
|
||||||
|
$bankOk = !empty($line['kodbank']) && !empty($line['noakaun']);
|
||||||
|
@endphp
|
||||||
|
<tr class="{{ $isRejected ? 'table-warning' : ($isVerified ? 'table-success' : '') }}">
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" class="row-check" name="ids[]" value="{{ $line['id'] }}">
|
<input type="checkbox"
|
||||||
|
class="row-check"
|
||||||
|
name="ids[]"
|
||||||
|
value="{{ $line['id'] }}"
|
||||||
|
{{ $isVerified ? '' : 'disabled' }}
|
||||||
|
title="{{ $isVerified ? '' : 'Sahkan rekod ini dahulu' }}">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if(($line['status'] ?? '') === 'REJECTED_PC')
|
@if($isRejected)
|
||||||
<span class="badge badge-danger">REJECTED</span>
|
<span class="badge badge-danger">REJECTED</span>
|
||||||
|
@elseif($isVerified)
|
||||||
|
<span class="badge badge-success">SAH</span>
|
||||||
|
@if(!empty($line['pc_verified_by']))
|
||||||
|
<div class="small text-muted">{{ $line['pc_verified_by'] }}</div>
|
||||||
|
@endif
|
||||||
@else
|
@else
|
||||||
<span class="badge badge-secondary">PENDING</span>
|
<span class="badge badge-secondary">BELUM SEMAK</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $line['norujukan'] ?? '-' }}</td>
|
<td>{{ $line['norujukan'] ?? '-' }}</td>
|
||||||
@@ -144,7 +255,33 @@
|
|||||||
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
<td>{{ $line['noakaun'] ?? '-' }}</td>
|
||||||
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
<td class="text-right">{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}</td>
|
||||||
<td class="text-left small">{{ $line['reject_reason'] ?? '-' }}</td>
|
<td class="text-left small">{{ $line['reject_reason'] ?? '-' }}</td>
|
||||||
<td>
|
<td class="text-nowrap">
|
||||||
|
@if($isVerified)
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-secondary btn-unverify"
|
||||||
|
data-id="{{ $line['id'] }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
||||||
|
Batal
|
||||||
|
</button>
|
||||||
|
@else
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-success btn-verify"
|
||||||
|
{{ $bankOk ? '' : 'disabled' }}
|
||||||
|
title="{{ $bankOk ? 'Semak maklumat pelanggan' : 'Lengkapkan maklumat bank dahulu' }}"
|
||||||
|
data-id="{{ $line['id'] }}"
|
||||||
|
data-norujukan="{{ $line['norujukan'] ?? '' }}"
|
||||||
|
data-nama="{{ $line['nama_pelanggan'] ?? '' }}"
|
||||||
|
data-nokp="{{ $line['nokp'] ?? '' }}"
|
||||||
|
data-namabank="{{ $line['nama_bank'] ?? $line['kodbank'] ?? '' }}"
|
||||||
|
data-noakaun="{{ $line['noakaun'] ?? '' }}"
|
||||||
|
data-namaakaun="{{ $line['nama_akaun'] ?? '' }}"
|
||||||
|
data-pinjaman="{{ number_format((float)($line['pinjaman'] ?? 0), 2) }}"
|
||||||
|
data-nota="{{ $line['nota'] ?? '' }}"
|
||||||
|
data-sebab="{{ $line['reject_reason'] ?? '' }}"
|
||||||
|
data-bukti-akaun="{{ $line['bukti_akaun_file_id'] ?? '' }}">
|
||||||
|
Semak
|
||||||
|
</button>
|
||||||
|
@endif
|
||||||
<button type="button" class="btn btn-sm btn-info btn-edit"
|
<button type="button" class="btn btn-sm btn-info btn-edit"
|
||||||
data-id="{{ $line['id'] }}"
|
data-id="{{ $line['id'] }}"
|
||||||
data-kodbank="{{ $line['kodbank'] ?? '' }}"
|
data-kodbank="{{ $line['kodbank'] ?? '' }}"
|
||||||
@@ -152,7 +289,8 @@
|
|||||||
data-namaakaun="{{ $line['nama_akaun'] ?? '' }}"
|
data-namaakaun="{{ $line['nama_akaun'] ?? '' }}"
|
||||||
data-namabank="{{ $line['nama_bank'] ?? '' }}"
|
data-namabank="{{ $line['nama_bank'] ?? '' }}"
|
||||||
data-nota="{{ $line['nota'] ?? '' }}"
|
data-nota="{{ $line['nota'] ?? '' }}"
|
||||||
data-norujukan="{{ $line['norujukan'] ?? '' }}">
|
data-norujukan="{{ $line['norujukan'] ?? '' }}"
|
||||||
|
data-bukti-akaun="{{ $line['bukti_akaun_file_id'] ?? '' }}">
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
@@ -166,6 +304,9 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<form id="formUnverify" method="post" action="" class="d-none">
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -221,8 +362,8 @@
|
|||||||
|
|
||||||
{{-- Edit modal --}}
|
{{-- Edit modal --}}
|
||||||
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-hidden="true">
|
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog modal-xl" role="document" style="max-width:1140px;">
|
||||||
<form method="post" id="editForm" action="">
|
<form method="post" id="editForm" action="" enctype="multipart/form-data">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -231,29 +372,50 @@
|
|||||||
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="row">
|
||||||
<label>Bank</label>
|
<div class="col-md-4">
|
||||||
<select name="kodbank" id="editKodbank" class="form-control" required>
|
<div class="form-group">
|
||||||
<option value="">-- Pilih Bank --</option>
|
<label>Bank</label>
|
||||||
@foreach($banks as $bank)
|
<select name="kodbank" id="editKodbank" class="form-control" required>
|
||||||
<option value="{{ $bank['abbreviation'] }}" data-nama="{{ $bank['name'] }}">
|
<option value="">-- Pilih Bank --</option>
|
||||||
{{ $bank['name'] }}
|
@foreach($banks as $bank)
|
||||||
</option>
|
<option value="{{ $bank['abbreviation'] }}" data-nama="{{ $bank['name'] }}">
|
||||||
@endforeach
|
{{ $bank['name'] }}
|
||||||
</select>
|
</option>
|
||||||
<input type="hidden" name="nama_bank" id="editNamabank">
|
@endforeach
|
||||||
</div>
|
</select>
|
||||||
<div class="form-group">
|
<input type="hidden" name="nama_bank" id="editNamabank">
|
||||||
<label>No. Akaun</label>
|
</div>
|
||||||
<input type="text" name="noakaun" id="editNoakaun" class="form-control" required>
|
<div class="form-group">
|
||||||
</div>
|
<label>No. Akaun</label>
|
||||||
<div class="form-group">
|
<input type="text" name="noakaun" id="editNoakaun" class="form-control" required>
|
||||||
<label>Nama Akaun</label>
|
</div>
|
||||||
<input type="text" name="nama_akaun" id="editNamaakaun" class="form-control">
|
<div class="form-group">
|
||||||
</div>
|
<label>Nama Akaun</label>
|
||||||
<div class="form-group">
|
<input type="text" name="nama_akaun" id="editNamaakaun" class="form-control">
|
||||||
<label>Nota</label>
|
</div>
|
||||||
<textarea name="nota" id="editNota" class="form-control" rows="2"></textarea>
|
<div class="form-group">
|
||||||
|
<label>Slip Bank / Bukti Akaun</label>
|
||||||
|
<input type="file" name="bukti_akaun" id="editBuktiAkaun" class="form-control-file"
|
||||||
|
accept=".pdf,.jpg,.jpeg,.png,.gif">
|
||||||
|
<div id="editBuktiAkaunExisting" class="mt-2" style="display:none;">
|
||||||
|
<a href="#" id="editBuktiAkaunLink" class="btn btn-sm btn-outline-primary" target="_blank">
|
||||||
|
Lihat slip sedia ada
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">PDF / imej slip akaun bank pelanggan (maks 4MB)</small>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Nota</label>
|
||||||
|
<textarea name="nota" id="editNota" class="form-control" rows="2"></textarea>
|
||||||
|
</div>
|
||||||
|
<p class="small text-muted mb-0">Jika rekod sudah SAH, simpan akan batal semakan. Sila semak semula sebelum hantar.</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<label class="d-block">Pratonton SAG</label>
|
||||||
|
<iframe id="editSagFrame" title="Pratonton SAG" src="about:blank"
|
||||||
|
style="width:100%;height:70vh;border:1px solid #dee2e6;background:#f8f9fa;"></iframe>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@@ -265,24 +427,176 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{-- Verify one-by-one modal --}}
|
||||||
|
<div class="modal fade" id="verifyModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl" role="document" style="max-width:1140px;">
|
||||||
|
<form method="post" id="verifyForm" action="">
|
||||||
|
@csrf
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Semak Rekod — <span id="verifyNorujukan"></span></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p class="small text-muted">Bandingkan maklumat pelanggan dengan SAG / slip bank sebelum sahkan.</p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<table class="table table-sm table-bordered mb-3">
|
||||||
|
<tr>
|
||||||
|
<th style="width:40%">SAG</th>
|
||||||
|
<td id="verifySag"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Pelanggan</th>
|
||||||
|
<td id="verifyNama"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>No KP</th>
|
||||||
|
<td id="verifyNokp"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Bank</th>
|
||||||
|
<td id="verifyBank"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>No Akaun</th>
|
||||||
|
<td id="verifyNoakaun"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Nama Akaun</th>
|
||||||
|
<td id="verifyNamaakaun"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Pinjaman</th>
|
||||||
|
<td>RM <span id="verifyPinjaman"></span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Nota</th>
|
||||||
|
<td id="verifyNota"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="alert alert-warning py-2" id="verifySebabBox" style="display:none;">
|
||||||
|
<b>Sebab tolak Operasi:</b>
|
||||||
|
<div id="verifySebab"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-check mb-3">
|
||||||
|
<input type="checkbox" class="form-check-input" id="verifyConfirm" required>
|
||||||
|
<label class="form-check-label" for="verifyConfirm">
|
||||||
|
Saya sahkan maklumat pelanggan, bank dan amaun adalah betul.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<a href="#" id="verifyBuktiAkaunLink" class="btn btn-sm btn-outline-primary" target="_blank" style="display:none;">
|
||||||
|
Lihat Bukti Akaun Bank
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<label class="d-block">Pratonton SAG</label>
|
||||||
|
<iframe id="verifySagFrame" title="Pratonton SAG" src="about:blank"
|
||||||
|
style="width:100%;height:70vh;border:1px solid #dee2e6;background:#f8f9fa;"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
|
||||||
|
<button type="submit" class="btn btn-success">Sahkan Rekod Ini</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function syncSubmitButton() {
|
function syncSubmitButton() {
|
||||||
var n = $('.row-check:checked').length;
|
var n = $('.row-check:not(:disabled):checked').length;
|
||||||
$('#btnSubmitBatch').prop('disabled', n === 0);
|
$('#btnSubmitBatch').prop('disabled', n === 0);
|
||||||
$('#btnSubmitBatch').text(n ? ('Hantar Batch ke Operasi (' + n + ')') : 'Hantar Batch ke Operasi');
|
$('#btnSubmitBatch').text(n ? ('Hantar Batch ke Operasi (' + n + ')') : 'Hantar Batch ke Operasi');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#checkAll').on('change', function () {
|
$('#checkAll').on('change', function () {
|
||||||
$('.row-check').prop('checked', this.checked);
|
$('.row-check:not(:disabled)').prop('checked', this.checked);
|
||||||
syncSubmitButton();
|
syncSubmitButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('change', '.row-check', syncSubmitButton);
|
$(document).on('change', '.row-check', function () {
|
||||||
|
var enabled = $('.row-check:not(:disabled)');
|
||||||
|
$('#checkAll').prop('checked', enabled.length > 0 && enabled.filter(':checked').length === enabled.length);
|
||||||
|
syncSubmitButton();
|
||||||
|
});
|
||||||
|
|
||||||
$('#btnSubmitBatch').on('click', function () {
|
$('#btnSubmitBatch').on('click', function () {
|
||||||
if ($('.row-check:checked').length === 0) return;
|
var n = $('.row-check:not(:disabled):checked').length;
|
||||||
if (!confirm('Hantar rekod dipilih ke Operasi?')) return;
|
if (n === 0) return;
|
||||||
$('#formSubmitBatch').submit();
|
Swal.fire({
|
||||||
|
title: 'Hantar Batch ke Operasi?',
|
||||||
|
html: n + ' rekod yang sudah SAH akan dihantar sebagai <b>{{ $slotName }}</b>.'
|
||||||
|
+ '<br>Sila hantar sebelum cutoff <b>{{ $slotCutoff }}</b>.',
|
||||||
|
icon: 'question',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Hantar',
|
||||||
|
cancelButtonText: 'Batal',
|
||||||
|
allowOutsideClick: false
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$('#formSubmitBatch').submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn-unverify').on('click', function () {
|
||||||
|
var id = $(this).data('id');
|
||||||
|
var sag = $(this).data('norujukan') || '';
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Batal Semakan?',
|
||||||
|
html: 'Batal semakan <b>' + (sag || 'rekod ini') + '</b>?'
|
||||||
|
+ '<br>Rekod ini tidak boleh dihantar sehingga disemak semula.',
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Ya, Batal',
|
||||||
|
cancelButtonText: 'Tutup',
|
||||||
|
allowOutsideClick: false
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$('#formUnverify').attr('action', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/unverify");
|
||||||
|
$('#formUnverify').submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn-verify').on('click', function () {
|
||||||
|
var id = $(this).data('id');
|
||||||
|
var sebab = $(this).data('sebab') || '';
|
||||||
|
$('#verifyForm').attr('action', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/verify");
|
||||||
|
$('#verifyNorujukan').text($(this).data('norujukan'));
|
||||||
|
$('#verifySag').text($(this).data('norujukan') || '-');
|
||||||
|
$('#verifyNama').text($(this).data('nama') || '-');
|
||||||
|
$('#verifyNokp').text($(this).data('nokp') || '-');
|
||||||
|
$('#verifyBank').text($(this).data('namabank') || '-');
|
||||||
|
$('#verifyNoakaun').text($(this).data('noakaun') || '-');
|
||||||
|
$('#verifyNamaakaun').text($(this).data('namaakaun') || '-');
|
||||||
|
$('#verifyPinjaman').text($(this).data('pinjaman') || '0.00');
|
||||||
|
$('#verifyNota').text($(this).data('nota') || '-');
|
||||||
|
if (sebab) {
|
||||||
|
$('#verifySebab').text(sebab);
|
||||||
|
$('#verifySebabBox').show();
|
||||||
|
} else {
|
||||||
|
$('#verifySebabBox').hide();
|
||||||
|
}
|
||||||
|
$('#verifyConfirm').prop('checked', false);
|
||||||
|
$('#verifySagFrame').attr('src', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/sag");
|
||||||
|
if ($(this).data('buktiAkaun')) {
|
||||||
|
$('#verifyBuktiAkaunLink').attr('href', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/bukti-akaun").show();
|
||||||
|
} else {
|
||||||
|
$('#verifyBuktiAkaunLink').hide();
|
||||||
|
}
|
||||||
|
$('#verifyModal').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#verifyModal').on('hidden.bs.modal', function () {
|
||||||
|
$('#verifySagFrame').attr('src', 'about:blank');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.btn-edit').on('click', function () {
|
$('.btn-edit').on('click', function () {
|
||||||
@@ -294,11 +608,50 @@
|
|||||||
$('#editNamaakaun').val($(this).data('namaakaun'));
|
$('#editNamaakaun').val($(this).data('namaakaun'));
|
||||||
$('#editNamabank').val($(this).data('namabank'));
|
$('#editNamabank').val($(this).data('namabank'));
|
||||||
$('#editNota').val($(this).data('nota'));
|
$('#editNota').val($(this).data('nota'));
|
||||||
|
$('#editBuktiAkaun').val('');
|
||||||
|
$('#editSagFrame').attr('src', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/sag");
|
||||||
|
if ($(this).data('buktiAkaun')) {
|
||||||
|
$('#editBuktiAkaunLink').attr('href', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/bukti-akaun");
|
||||||
|
$('#editBuktiAkaunExisting').show();
|
||||||
|
} else {
|
||||||
|
$('#editBuktiAkaunExisting').hide();
|
||||||
|
}
|
||||||
$('#editModal').modal('show');
|
$('#editModal').modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#editModal').on('hidden.bs.modal', function () {
|
||||||
|
$('#editSagFrame').attr('src', 'about:blank');
|
||||||
|
});
|
||||||
|
|
||||||
$('#editKodbank').on('change', function () {
|
$('#editKodbank').on('change', function () {
|
||||||
$('#editNamabank').val($('#editKodbank option:selected').data('nama') || '');
|
$('#editNamabank').val($('#editKodbank option:selected').data('nama') || '');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function pad2(n) {
|
||||||
|
return n < 10 ? '0' + n : String(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tickSlotCountdown() {
|
||||||
|
var el = document.getElementById('slotCountdown');
|
||||||
|
if (!el) return;
|
||||||
|
if (el.getAttribute('data-lewat') === '1') return;
|
||||||
|
var cutoff = el.getAttribute('data-cutoff') || '';
|
||||||
|
var parts = cutoff.split(':');
|
||||||
|
if (parts.length < 2) return;
|
||||||
|
var now = new Date();
|
||||||
|
var end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), parseInt(parts[0], 10), parseInt(parts[1], 10), 0);
|
||||||
|
var diff = end - now;
|
||||||
|
if (diff <= 0) {
|
||||||
|
el.textContent = 'Cutoff telah tamat — sila muat semula halaman';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var h = Math.floor(diff / 3600000);
|
||||||
|
var m = Math.floor((diff % 3600000) / 60000);
|
||||||
|
var s = Math.floor((diff % 60000) / 1000);
|
||||||
|
el.textContent = 'Baki masa: ' + h + 'j ' + pad2(m) + 'm ' + pad2(s) + 's';
|
||||||
|
}
|
||||||
|
|
||||||
|
tickSlotCountdown();
|
||||||
|
setInterval(tickSlotCountdown, 1000);
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
{{-- <div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h5 class="mb-0">Tutup Modal Online (EOD)</h5>
|
<h5 class="mb-0">Tutup Modal Online (EOD)</h5>
|
||||||
</div>
|
</div>
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
</form>
|
</form>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> --}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-7 mb-3">
|
<div class="col-md-7 mb-3">
|
||||||
|
|||||||
@@ -326,6 +326,16 @@
|
|||||||
<input type="text" id="jumlahtelahdibayar" class="form-control" readonly/>
|
<input type="text" id="jumlahtelahdibayar" class="form-control" readonly/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-4">
|
||||||
|
REBET DISKAUN (RM)
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<input type="text" id="jumlahDiskaun" value="{{ number_format($gadai['diskaun'] ?? 0, 2) }}" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -441,6 +451,16 @@
|
|||||||
<input type="text" id="jumlahupah" class="form-control" readonly/>
|
<input type="text" id="jumlahupah" class="form-control" readonly/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-4">
|
||||||
|
REBET DISKAUN (RM)
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<input type="text" id="jumlahDiskaun" value="{{ number_format($gadai['diskaun'] ?? 0, 2) }}" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div id="divbakipinjaman">
|
<div id="divbakipinjaman">
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
@@ -467,6 +487,17 @@
|
|||||||
<input type="text" id="jumlahtelahdibayar" class="form-control" readonly/>
|
<input type="text" id="jumlahtelahdibayar" class="form-control" readonly/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-4">
|
||||||
|
REBET DISKAUN (RM)
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<input type="text" id="jumlahDiskaun" value="{{ number_format($gadai['diskaun'] ?? 0, 2) }}" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group row" id="divbayaran">
|
<div class="form-group row" id="divbayaran">
|
||||||
|
|||||||
@@ -214,8 +214,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>Borang Kelulusan Pembiayaan Online<br>Senarai Batch Pembayaran</h1>
|
<h1>Borang Kelulusan Batch Pembiayaan Online</h1>
|
||||||
<p>Untuk semakan Operasi dan kelulusan Pengurus Besar. Bukan untuk tandatangan pelanggan.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
@@ -298,8 +297,8 @@
|
|||||||
bagi batch <b>{{ $batchNo }}</b> cawangan <b>{{ $cawangan }}</b> adalah lengkap
|
bagi batch <b>{{ $batchNo }}</b> cawangan <b>{{ $cawangan }}</b> adalah lengkap
|
||||||
untuk proses pembayaran ke akaun bank pelanggan.
|
untuk proses pembayaran ke akaun bank pelanggan.
|
||||||
<ol>
|
<ol>
|
||||||
<li>Maklumat SAG, nama, no. KP, bank dan no. akaun telah disemak terhadap rekod sistem.</li>
|
<li>Maklumat SAG, nama, no. KP, bank dan no. akaun telah disemak didalam sistem.</li>
|
||||||
<li>Pembayaran akan dikreditkan ke akaun penerima seperti senarai, bukan tunai di kaunter.</li>
|
<li>Pembayaran akan dikreditkan ke akaun penerima seperti didalam senarai.</li>
|
||||||
<li>Sebarang ralat akaun yang dikesan selepas kelulusan hendaklah dilaporkan serta-merta.</li>
|
<li>Sebarang ralat akaun yang dikesan selepas kelulusan hendaklah dilaporkan serta-merta.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
@@ -318,18 +317,11 @@
|
|||||||
<div class="role">Pengurus Besar</div>
|
<div class="role">Pengurus Besar</div>
|
||||||
<div class="sign-line">
|
<div class="sign-line">
|
||||||
<p>Nama:</p>
|
<p>Nama:</p>
|
||||||
<p>Cop / Paraf:</p>
|
<p>Cop:</p>
|
||||||
<p>Tarikh:</p>
|
<p>Tarikh:</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-print.footer :show-copies="false">
|
|
||||||
<b>Nota:</b>
|
|
||||||
<p>1. Borang ini dicetak dari skrin Operasi — Pembiayaan Online (Batch) untuk kelulusan pembayaran.</p>
|
|
||||||
<p>2. Hanya dua tandatangan diperlukan: Operasi dan Pengurus Besar.</p>
|
|
||||||
<p>3. Simpan salinan bersama bukti pindahan bank selepas status PAID.</p>
|
|
||||||
</x-print.footer>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -108,6 +108,19 @@
|
|||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.copies {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
.copies span {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #111;
|
||||||
|
width: 11px;
|
||||||
|
height: 11px;
|
||||||
|
margin-right: 4px;
|
||||||
|
vertical-align: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.akuan {
|
.akuan {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
@@ -121,10 +134,8 @@
|
|||||||
.akuan li { margin-bottom: 4px; }
|
.akuan li { margin-bottom: 4px; }
|
||||||
|
|
||||||
.signs {
|
.signs {
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr 1fr;
|
|
||||||
gap: 10px;
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
max-width: 34%;
|
||||||
}
|
}
|
||||||
.sign-box {
|
.sign-box {
|
||||||
border: 1px solid #111;
|
border: 1px solid #111;
|
||||||
@@ -184,7 +195,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Online (Akaun Bank)</h1>
|
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Atas Talian (Online)</h1>
|
||||||
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
|
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -214,7 +225,7 @@
|
|||||||
<div class="section-title">B. Maklumat Pembiayaan</div>
|
<div class="section-title">B. Maklumat Pembiayaan</div>
|
||||||
<table class="fields">
|
<table class="fields">
|
||||||
<tr>
|
<tr>
|
||||||
<th>No. Surat Akuan Gadai</th>
|
<th>No. Surat Akuan Gadaian (SAG)</th>
|
||||||
<td>{{ $norujukan }}</td>
|
<td>{{ $norujukan }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -222,8 +233,8 @@
|
|||||||
<td class="amt">RM {{ $pinjaman }}</td>
|
<td class="amt">RM {{ $pinjaman }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Cara Terima Pembiayaan</th>
|
<th>Cara Pembiayaan</th>
|
||||||
<td>Online (kredit ke akaun bank) — bukan tunai</td>
|
<td>Atas Talian (Online)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Teller</th>
|
<th>Teller</th>
|
||||||
@@ -250,15 +261,19 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="copies">
|
||||||
|
Salinan: <span></span> Kad Pengenalan <span></span> Akaun Bank/ Slip/ Penyata Bank
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="section-title">D. Akuan Pelanggan</div>
|
<div class="section-title">D. Akuan Pelanggan</div>
|
||||||
<div class="akuan">
|
<div class="akuan">
|
||||||
Saya, <b>{{ $nama }}</b> (No. KP: <b>{{ $nokp }}</b>), dengan ini mengesahkan bahawa:
|
Saya, <b>{{ $nama }}</b> (No. KP: <b>{{ $nokp }}</b>), dengan ini mengesahkan bahawa:
|
||||||
<ol>
|
<ol>
|
||||||
<li>Maklumat akaun bank di Bahagian C adalah benar, tepat, dan milik saya sendiri.</li>
|
<li>Maklumat akaun bank di Bahagian C adalah benar, tepat, dan milik saya sendiri.</li>
|
||||||
<li>Saya memohon supaya amaun pembiayaan gadai sebanyak <b>RM {{ $pinjaman }}</b> dikreditkan ke akaun tersebut dan <b>bukan</b> diterima secara tunai.</li>
|
<li>Saya bersetuju menerima pembayaran pembiayaan Ar-Rahn KoPKB sebanyak <b>RM {{ $pinjaman }}</b> secara atas talian (Online) ke akaun tersebut.</li>
|
||||||
<li>Saya faham kredit ke akaun tertakluk kepada semakan Pengurus Cawangan dan proses pembayaran pihak Koperasi.</li>
|
<li>Saya memahami bahawa pihak Ar-Rahn KoPKB tidak akan bertanggungjawab atas sebarang kesilapan akibat maklumat akaun yang diberikan oleh saya.</li>
|
||||||
<li>Saya bertanggungjawab sepenuhnya jika maklumat akaun tidak tepat, dan tidak akan menuntut ganti rugi atas kelewatan atau ralat yang berpunca daripadanya.</li>
|
<li>Saya mengesahkan bahawa segala maklumat yang diberikan adalah benar dan tepat.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -272,29 +287,13 @@
|
|||||||
<p>Tarikh: {{ $tarikh }}</p>
|
<p>Tarikh: {{ $tarikh }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sign-box">
|
|
||||||
<div class="role">Tandatangan Teller</div>
|
|
||||||
<div class="sign-line">
|
|
||||||
<p>Nama: {{ $teller }}</p>
|
|
||||||
<p>Cop / Paraf:</p>
|
|
||||||
<p>Tarikh: {{ $tarikh }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sign-box">
|
|
||||||
<div class="role">Pengurus Cawangan</div>
|
|
||||||
<div class="sign-line">
|
|
||||||
<p>Nama:</p>
|
|
||||||
<p>Cop cawangan:</p>
|
|
||||||
<p>Tarikh:</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-print.footer>
|
<x-print.footer :show-copies="false">
|
||||||
<b>Nota:</b>
|
<b>Nota:</b>
|
||||||
<p>1. Borang ini dicetak semasa pelanggan memilih cara terima pembiayaan secara Online.</p>
|
<p>1. Pembayaran hanya dibuat ke akaun pelanggan sendiri.</p>
|
||||||
<p>2. Pembiayaan akan dikreditkan ke akaun selepas semakan PC. Pelanggan tidak menerima wang tunai di kaunter.</p>
|
<p>2. Sebarang pembetulan maklumat hendaklah disahkan semula oleh pelanggan.</p>
|
||||||
<p>3. Sila pastikan nama pemegang akaun sepadan dengan nama pelanggan pada MyKad.</p>
|
<p>3. Borang ini hendaklah dilampirkan bersama dokumen transaksi gadaian untuk tujuan audit dan rekod.</p>
|
||||||
</x-print.footer>
|
</x-print.footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -233,7 +233,9 @@
|
|||||||
@endif
|
@endif
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td style="width:100px">{{$item['norujukan']}}</td>
|
<td style="width:100px">{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ $item['nama'] }}
|
{{ $item['nama'] }}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@php $rebetAnnur = !empty(($cawangan_info['features'] ?? [])['rebet_annur']); @endphp
|
||||||
<style>
|
<style>
|
||||||
#header {
|
#header {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
@@ -230,6 +231,9 @@
|
|||||||
<th>Lain-Lain Caj (RM)</th>
|
<th>Lain-Lain Caj (RM)</th>
|
||||||
<th>Keuntungan 1% (RM)</th>
|
<th>Keuntungan 1% (RM)</th>
|
||||||
<th>Keuntungan</th>
|
<th>Keuntungan</th>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<th>Diskaun Rebet</th>
|
||||||
|
@endif
|
||||||
<th>Peratus (%)</th>
|
<th>Peratus (%)</th>
|
||||||
</tr>
|
</tr>
|
||||||
@php
|
@php
|
||||||
@@ -241,6 +245,7 @@
|
|||||||
$bil = 0;
|
$bil = 0;
|
||||||
$full_total_ujrah = 0;
|
$full_total_ujrah = 0;
|
||||||
$full_total_onepercent = 0;
|
$full_total_onepercent = 0;
|
||||||
|
$totaldiskaun = 0;
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
@foreach($gadai as $index=>$item)
|
@foreach($gadai as $index=>$item)
|
||||||
@@ -251,6 +256,7 @@
|
|||||||
$totalupah += $item['upah12'];
|
$totalupah += $item['upah12'];
|
||||||
$full_total_ujrah += $item['ujrah']*12;
|
$full_total_ujrah += $item['ujrah']*12;
|
||||||
$full_total_onepercent += $item['onepercent']*12;
|
$full_total_onepercent += $item['onepercent']*12;
|
||||||
|
$totaldiskaun += $item['diskaun'] ?? 0;
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
@if($index > 0)
|
@if($index > 0)
|
||||||
@@ -264,6 +270,7 @@
|
|||||||
$totalberatteller = 0;
|
$totalberatteller = 0;
|
||||||
$totalujrah = 0;
|
$totalujrah = 0;
|
||||||
$totalonepercent = 0;
|
$totalonepercent = 0;
|
||||||
|
$totaldiskaunteller = 0;
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
@endif
|
@endif
|
||||||
@@ -278,12 +285,15 @@
|
|||||||
$totalupah12 = 0;
|
$totalupah12 = 0;
|
||||||
$totalujrah = 0;
|
$totalujrah = 0;
|
||||||
$totalonepercent= 0;
|
$totalonepercent= 0;
|
||||||
|
$totaldiskaunteller = 0;
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td style="width:100px">{{$item['norujukan']}}</td>
|
<td style="width:100px">{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ $item['nama'] }}
|
{{ $item['nama'] }}
|
||||||
</td>
|
</td>
|
||||||
@@ -301,6 +311,9 @@
|
|||||||
<td>{{ number_format($item['ujrah']*12,2) }}</td>
|
<td>{{ number_format($item['ujrah']*12,2) }}</td>
|
||||||
<td>{{ number_format($item['onepercent']*12,2) }}</td>
|
<td>{{ number_format($item['onepercent']*12,2) }}</td>
|
||||||
<td>{{ number_format($item['upah12'],2) }}</td>
|
<td>{{ number_format($item['upah12'],2) }}</td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td>{{ number_format($item['diskaun'] ?? 0,2) }}</td>
|
||||||
|
@endif
|
||||||
<td>{{ $item['percentpinj'] }}</td>
|
<td>{{ $item['percentpinj'] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@php $counter++; @endphp
|
@php $counter++; @endphp
|
||||||
@@ -311,6 +324,7 @@
|
|||||||
$totalupah12 += $item['upah12'];
|
$totalupah12 += $item['upah12'];
|
||||||
$totalujrah += $item['ujrah']*12;
|
$totalujrah += $item['ujrah']*12;
|
||||||
$totalonepercent += $item['onepercent']*12;
|
$totalonepercent += $item['onepercent']*12;
|
||||||
|
$totaldiskaunteller += $item['diskaun'] ?? 0;
|
||||||
|
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
@@ -325,6 +339,9 @@
|
|||||||
<td><b>{{ number_format($totalujrah,2) }}</b></td>
|
<td><b>{{ number_format($totalujrah,2) }}</b></td>
|
||||||
<td><b>{{ number_format($totalonepercent,2) }}</b></td>
|
<td><b>{{ number_format($totalonepercent,2) }}</b></td>
|
||||||
<td><b>{{ number_format($totalupah12,2) }} </b></td>
|
<td><b>{{ number_format($totalupah12,2) }} </b></td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td><b>{{ number_format($totaldiskaunteller,2) }} </b></td>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@@ -335,6 +352,7 @@
|
|||||||
$totalnmteller = 0;
|
$totalnmteller = 0;
|
||||||
$totalujrah = 0;
|
$totalujrah = 0;
|
||||||
$totalonepercent = 0;
|
$totalonepercent = 0;
|
||||||
|
$totaldiskaunteller = 0;
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
@endif
|
@endif
|
||||||
@@ -348,6 +366,9 @@
|
|||||||
<td><b>{{ number_format($totalujrah,2) }}</b></td>
|
<td><b>{{ number_format($totalujrah,2) }}</b></td>
|
||||||
<td><b>{{ number_format($totalonepercent,2) }}</b></td>
|
<td><b>{{ number_format($totalonepercent,2) }}</b></td>
|
||||||
<td><b>{{ number_format($totalupah12,2) }} </b></td>
|
<td><b>{{ number_format($totalupah12,2) }} </b></td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td><b>{{ number_format($totaldiskaunteller,2) }} </b></td>
|
||||||
|
@endif
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -219,7 +219,9 @@
|
|||||||
@php if($item['hargajualan'] == null) $totalpinjaman += $item['pinjaman']; else $totalpinjaman += $item['bakipjm']; @endphp
|
@php if($item['hargajualan'] == null) $totalpinjaman += $item['pinjaman']; else $totalpinjaman += $item['bakipjm']; @endphp
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td>{{$item['norujukan']}}</td>
|
<td>{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>{{ $item['tempoh'] }}</td>
|
<td>{{ $item['tempoh'] }}</td>
|
||||||
<td>{{$item['nokp']}}</td>
|
<td>{{$item['nokp']}}</td>
|
||||||
<td>{{ number_format($item['berat'],2) }}</td>
|
<td>{{ number_format($item['berat'],2) }}</td>
|
||||||
|
|||||||
@@ -213,7 +213,9 @@
|
|||||||
@php if($item['hargajualan'] == null) $totalpinjaman += $item['pinjaman']; else $totalpinjaman += $item['bakipjm']; @endphp
|
@php if($item['hargajualan'] == null) $totalpinjaman += $item['pinjaman']; else $totalpinjaman += $item['bakipjm']; @endphp
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td>{{$item['norujukan']}}</td>
|
<td>{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>{{ $item['jbg'] }}</td>
|
<td>{{ $item['jbg'] }}</td>
|
||||||
<td>{{$item['nokp']}}</td>
|
<td>{{$item['nokp']}}</td>
|
||||||
<td>{{ number_format($item['berat'],2) }}</td>
|
<td>{{ number_format($item['berat'],2) }}</td>
|
||||||
|
|||||||
@@ -236,7 +236,9 @@
|
|||||||
@endphp
|
@endphp
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td>{{$item['norujukan']}}</td>
|
<td>{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>{{ $item['tempoh'] }}</td>
|
<td>{{ $item['tempoh'] }}</td>
|
||||||
<td>{{$item['nokp']}}</td>
|
<td>{{$item['nokp']}}</td>
|
||||||
<td>{{ number_format($item['berat'],2) }}</td>
|
<td>{{ number_format($item['berat'],2) }}</td>
|
||||||
@@ -342,7 +344,9 @@
|
|||||||
@endphp
|
@endphp
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ $counter }}</td>
|
<td>{{ $counter }}</td>
|
||||||
<td>{{$item['norujukan']}}</td>
|
<td>{{$item['norujukan']}}<br>
|
||||||
|
@include('print.tag_cara_terima', ['caraTerima' => $item['cara_terima'] ?? null])
|
||||||
|
</td>
|
||||||
<td>{{ $item['jbg'] }}</td>
|
<td>{{ $item['jbg'] }}</td>
|
||||||
<td>{{$item['nokp']}}</td>
|
<td>{{$item['nokp']}}</td>
|
||||||
<td>{{ number_format($item['berat'],2) }}</td>
|
<td>{{ number_format($item['berat'],2) }}</td>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@php $rebetAnnur = !empty(($cawangan_info['features'] ?? [])['rebet_annur']); @endphp
|
||||||
<style>
|
<style>
|
||||||
#header {
|
#header {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
@@ -241,6 +242,9 @@
|
|||||||
<th>B.Pembiayaan(RM)</th>
|
<th>B.Pembiayaan(RM)</th>
|
||||||
<th>Lain-Lain Caj (RM)</th>
|
<th>Lain-Lain Caj (RM)</th>
|
||||||
<th>Untung 1% (RM)</th>
|
<th>Untung 1% (RM)</th>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<th>Diskaun Rebet (RM)</th>
|
||||||
|
@endif
|
||||||
<th>Pendapatan(RM)</th>
|
<th>Pendapatan(RM)</th>
|
||||||
<th>Bayaran(RM)</th>
|
<th>Bayaran(RM)</th>
|
||||||
<th>Jumlah(RM)</th>
|
<th>Jumlah(RM)</th>
|
||||||
@@ -254,6 +258,7 @@
|
|||||||
$totalupah = 0;
|
$totalupah = 0;
|
||||||
$totalujrah = 0;
|
$totalujrah = 0;
|
||||||
$totalonepercent = 0;
|
$totalonepercent = 0;
|
||||||
|
$totaldiskaunrebate = 0;
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@foreach ($tebus as $index => $item)
|
@foreach ($tebus as $index => $item)
|
||||||
@@ -266,6 +271,7 @@
|
|||||||
$totalnm += $item['nilaimarhun'];
|
$totalnm += $item['nilaimarhun'];
|
||||||
$totalujrah += $item['ujrah'];
|
$totalujrah += $item['ujrah'];
|
||||||
$totalonepercent += $item['onepercent'];
|
$totalonepercent += $item['onepercent'];
|
||||||
|
$totaldiskaunrebate += $item['diskaun_rebate'] ?? 0;
|
||||||
|
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@@ -282,6 +288,7 @@
|
|||||||
$totalbayaranteller = 0;
|
$totalbayaranteller = 0;
|
||||||
$totalujrahteller = 0;
|
$totalujrahteller = 0;
|
||||||
$totalonepercentteller = 0;
|
$totalonepercentteller = 0;
|
||||||
|
$totaldiskaunrebateteller = 0;
|
||||||
@endphp
|
@endphp
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@@ -297,6 +304,7 @@
|
|||||||
$totaljumlahteller = 0;
|
$totaljumlahteller = 0;
|
||||||
$totalujrahteller = 0;
|
$totalujrahteller = 0;
|
||||||
$totalonepercentteller = 0;
|
$totalonepercentteller = 0;
|
||||||
|
$totaldiskaunrebateteller = 0;
|
||||||
@endphp
|
@endphp
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -336,6 +344,9 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>{{ number_format($item['ujrah'], 2) }}</td>
|
<td>{{ number_format($item['ujrah'], 2) }}</td>
|
||||||
<td>{{ number_format($item['onepercent'], 2) }}</td>
|
<td>{{ number_format($item['onepercent'], 2) }}</td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td>{{ number_format($item['diskaun_rebate'] ?? 0, 2) }}</td>
|
||||||
|
@endif
|
||||||
{{-- <td>{{ number_format($item['bakiupah'], 2) }}</td> --}}
|
{{-- <td>{{ number_format($item['bakiupah'], 2) }}</td> --}}
|
||||||
<td>
|
<td>
|
||||||
@php
|
@php
|
||||||
@@ -371,6 +382,7 @@
|
|||||||
$totalbayaranteller += $item['bakipjm']; //
|
$totalbayaranteller += $item['bakipjm']; //
|
||||||
$totalujrahteller += $item['ujrah'];
|
$totalujrahteller += $item['ujrah'];
|
||||||
$totalonepercentteller += $item['onepercent'];
|
$totalonepercentteller += $item['onepercent'];
|
||||||
|
$totaldiskaunrebateteller += $item['diskaun_rebate'] ?? 0;
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@php
|
@php
|
||||||
@@ -388,6 +400,9 @@
|
|||||||
<td><b>{{ number_format($totalpinjamanteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalpinjamanteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalujrahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalujrahteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalonepercentteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalonepercentteller, 2) }} </b></td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td><b>{{ number_format($totaldiskaunrebateteller ?? 0, 2) }} </b></td>
|
||||||
|
@endif
|
||||||
<td><b>{{ number_format($totalupahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalupahteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalbayaranteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalbayaranteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totaljumlahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totaljumlahteller, 2) }} </b></td>
|
||||||
@@ -402,6 +417,7 @@
|
|||||||
$totaljumlahteller = 0;
|
$totaljumlahteller = 0;
|
||||||
$totalujrahteller = 0;
|
$totalujrahteller = 0;
|
||||||
$totalonepercentteller = 0;
|
$totalonepercentteller = 0;
|
||||||
|
$totaldiskaunrebateteller = 0;
|
||||||
@endphp
|
@endphp
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@@ -412,6 +428,9 @@
|
|||||||
<td><b>{{ number_format($totalpinjamanteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalpinjamanteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalujrahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalujrahteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalonepercentteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalonepercentteller, 2) }} </b></td>
|
||||||
|
@if($rebetAnnur)
|
||||||
|
<td><b>{{ number_format($totaldiskaunrebateteller ?? 0, 2) }} </b></td>
|
||||||
|
@endif
|
||||||
<td><b>{{ number_format($totalupahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalupahteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totalbayaranteller, 2) }} </b></td>
|
<td><b>{{ number_format($totalbayaranteller, 2) }} </b></td>
|
||||||
<td><b>{{ number_format($totaljumlahteller, 2) }} </b></td>
|
<td><b>{{ number_format($totaljumlahteller, 2) }} </b></td>
|
||||||
|
|||||||
@@ -631,27 +631,34 @@
|
|||||||
<td style="width:10px">Keuntungan</td>
|
<td style="width:10px">Keuntungan</td>
|
||||||
<td style="width:10px">: RM {{ number_format($transaction_tebus['onepercent'],2) }}</td>
|
<td style="width:10px">: RM {{ number_format($transaction_tebus['onepercent'],2) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
{{-- <tr>
|
||||||
<td style="width:10px">(-) Rebat Untung</td>
|
<td style="width:10px">(-) Rebat Untung</td>
|
||||||
<td style="width:10px">: RM
|
<td style="width:10px">: RM
|
||||||
{{ number_format($keuntungan_rebate,2) }}
|
{{ number_format($keuntungan_rebate,2) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr> --}}
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:10px">Lain-Lain Caj</td>
|
<td style="width:10px">Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: RM {{ number_format($transaction_tebus['ujrah'],2) }} </td>
|
<td style="width:10px">: RM {{ number_format($transaction_tebus['ujrah'],2) }} </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
{{-- <tr>
|
||||||
<td style="width:10px">(-) Rebat Lain-Lain Caj</td>
|
<td style="width:10px">(-) Rebat Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: RM
|
<td style="width:10px">: RM
|
||||||
{{ number_format($ujrah_rebate, 2) }} </td>
|
{{ number_format($ujrah_rebate, 2) }} </td>
|
||||||
</tr>
|
</tr> --}}
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:10px">Jumlah Keuntungan + Lain-Lain Caj</td>
|
<td style="width:10px">Jumlah Keuntungan + Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: <strong>RM
|
<td style="width:10px">: <strong>RM
|
||||||
{{ number_format($penebusan['onepercent'] + $penebusan['ujrah'], 2) }}</strong>
|
{{ number_format($penebusan['onepercent'] + $penebusan['ujrah'], 2) }}</strong>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<tr>
|
||||||
|
<td style="width:10px">(-) Diskaun Promosi</td>
|
||||||
|
<td style="width:10px">: RM
|
||||||
|
{{ number_format($gadai['diskaun'] ?? 0, 2) }} </td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -864,27 +871,34 @@
|
|||||||
<td style="width:10px">Keuntungan</td>
|
<td style="width:10px">Keuntungan</td>
|
||||||
<td style="width:10px">: RM {{ number_format($transaction_tebus['onepercent'], 2) }}</td>
|
<td style="width:10px">: RM {{ number_format($transaction_tebus['onepercent'], 2) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
{{-- <tr>
|
||||||
<td style="width:10px">(-) Rebat Untung</td>
|
<td style="width:10px">(-) Rebat Untung</td>
|
||||||
<td style="width:10px">: RM
|
<td style="width:10px">: RM
|
||||||
{{ number_format($keuntungan_rebate, 2) }}
|
{{ number_format($keuntungan_rebate, 2) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr> --}}
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:10px">Lain-Lain Caj</td>
|
<td style="width:10px">Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: RM {{ number_format($transaction_tebus['ujrah'], 2) }} </td>
|
<td style="width:10px">: RM {{ number_format($transaction_tebus['ujrah'], 2) }} </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
{{-- <tr>
|
||||||
<td style="width:10px">(-) Rebat Lain-Lain Caj</td>
|
<td style="width:10px">(-) Rebat Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: RM
|
<td style="width:10px">: RM
|
||||||
{{ number_format($ujrah_rebate, 2) }} </td>
|
{{ number_format($ujrah_rebate, 2) }} </td>
|
||||||
</tr>
|
</tr> --}}
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:10px">Jumlah Keuntungan + Lain-Lain Caj</td>
|
<td style="width:10px">Jumlah Keuntungan + Lain-Lain Caj</td>
|
||||||
<td style="width:10px">: <strong>RM
|
<td style="width:10px">: <strong>RM
|
||||||
{{ number_format($penebusan['onepercent'] + $penebusan['ujrah'], 2) }}</strong>
|
{{ number_format($penebusan['onepercent'] + $penebusan['ujrah'], 2) }}</strong>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if(!empty(($cawangan_info['features'] ?? [])['rebet_annur']))
|
||||||
|
<tr>
|
||||||
|
<td style="width:10px">(-) Diskaun Promosi</td>
|
||||||
|
<td style="width:10px">: RM
|
||||||
|
{{ number_format($gadai['diskaun'] ?? 0, 2) }} </td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
if (window.self !== window.top) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
window.print();
|
window.print();
|
||||||
window.onfocus=function(){ window.close();}
|
window.onfocus=function(){ window.close();}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -395,6 +395,9 @@
|
|||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
if (window.self !== window.top) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
window.print();
|
window.print();
|
||||||
window.onfocus = function() {
|
window.onfocus = function() {
|
||||||
window.close();
|
window.close();
|
||||||
@@ -2109,6 +2112,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="main-page" style="font-family: Arial, Helvetica, sans-serif;">
|
<div class="main-page" style="font-family: Arial, Helvetica, sans-serif;">
|
||||||
<div class="sub-page" style="font-size: 11px;">
|
<div class="sub-page" style="font-size: 11px;">
|
||||||
|
@php
|
||||||
|
$caraTerimaBayaran = strtoupper(trim((string) ($gadai_detail['cara_terima'] ?? '')));
|
||||||
|
@endphp
|
||||||
|
<div style="border: 1px solid black; padding: 10px 12px; margin-bottom: 10px; break-inside: avoid;">
|
||||||
|
<div style="font-size: 13px; font-weight: bold; margin-bottom: 12px;">CARA TERIMA BAYARAN</div>
|
||||||
|
<div style="display: flex; align-items: center; gap: 40px; font-size: 12px; font-weight: bold;">
|
||||||
|
<span style="display: inline-flex; align-items: center; gap: 8px;">
|
||||||
|
<span style="display: inline-block; width: 14px; height: 14px; border: 1px solid black; text-align: center; line-height: 12px;">@if ($caraTerimaBayaran === 'TUNAI')✓@endif</span>
|
||||||
|
TUNAI
|
||||||
|
</span>
|
||||||
|
<span style="display: inline-flex; align-items: center; gap: 8px;">
|
||||||
|
<span style="display: inline-block; width: 14px; height: 14px; border: 1px solid black; text-align: center; line-height: 12px;">@if ($caraTerimaBayaran === 'ONLINE')✓@endif</span>
|
||||||
|
KREDIT KE AKAUN
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{-- HEADER SECTION --}}
|
{{-- HEADER SECTION --}}
|
||||||
<table style="width: 100%; margin-top: 0;">
|
<table style="width: 100%; margin-top: 0;">
|
||||||
<tr style="vertical-align: top;">
|
<tr style="vertical-align: top;">
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@php
|
||||||
|
$caraTerimaTag = strtoupper(trim((string) ($caraTerima ?? '')));
|
||||||
|
$caraTerimaLabel = ['TUNAI' => 'TUNAI', 'ONLINE' => 'ONLINE'][$caraTerimaTag] ?? 'TIDAK DINYATAKAN';
|
||||||
|
$caraTerimaWarna = ['TUNAI' => '#166534', 'ONLINE' => '#1e40af'][$caraTerimaTag] ?? '#555555';
|
||||||
|
@endphp
|
||||||
|
<span title="Cara Terima Bayaran" style="display: inline-block; margin-top: 3px; padding: 2px 5px; border: 1px solid {{ $caraTerimaWarna }}; border-radius: 3px; color: {{ $caraTerimaWarna }}; font-size: 9px; font-weight: bold; line-height: 1.2; white-space: nowrap;">{{ $caraTerimaLabel }}</span>
|
||||||
@@ -15,6 +15,8 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Route::post('/internal/notifications', ['as' => 'internal.notifications.store', 'uses' => 'InternalNotificationController@store']);
|
||||||
|
|
||||||
Route::get('/health', function () {
|
Route::get('/health', function () {
|
||||||
return response()->json(['status' => 'ok']);
|
return response()->json(['status' => 'ok']);
|
||||||
});
|
});
|
||||||
@@ -174,6 +176,7 @@ Route::get('/khazanahtebus',['as'=>'khazanah.tebus','uses'=>'KhazanahController@
|
|||||||
Route::get('/kelulusan','KhazanahController@kelulusan')->middleware('auth','khazanah');
|
Route::get('/kelulusan','KhazanahController@kelulusan')->middleware('auth','khazanah');
|
||||||
Route::get('/kelulusanrekodlepas',['as'=>'khazanah.rekodlepas','uses'=>'KhazanahController@kelulusanrekodlepas'])->middleware('auth','khazanah');
|
Route::get('/kelulusanrekodlepas',['as'=>'khazanah.rekodlepas','uses'=>'KhazanahController@kelulusanrekodlepas'])->middleware('auth','khazanah');
|
||||||
Route::get('/kelulusanrekodlepasoperasi',['as'=>'operasi.rekodlepas','uses'=>'OperasiController@kelulusanrekodlepas'])->middleware('auth','operasi');
|
Route::get('/kelulusanrekodlepasoperasi',['as'=>'operasi.rekodlepas','uses'=>'OperasiController@kelulusanrekodlepas'])->middleware('auth','operasi');
|
||||||
|
Route::get('/kelulusanrekodlepasoperasi/data',['as'=>'operasi.rekodlepas.data','uses'=>'OperasiController@kelulusanrekodlepasData'])->middleware('auth','operasi');
|
||||||
Route::get('/pendahuluan',['as'=>'khazanah.pendahulu','uses'=>'KhazanahController@pendahuluan'])->middleware('auth','khazanah');
|
Route::get('/pendahuluan',['as'=>'khazanah.pendahulu','uses'=>'KhazanahController@pendahuluan'])->middleware('auth','khazanah');
|
||||||
Route::get('/serahan',['as'=>'khazanah.serahan','uses'=>'KhazanahController@serahan'])->middleware('auth','khazanah');
|
Route::get('/serahan',['as'=>'khazanah.serahan','uses'=>'KhazanahController@serahan'])->middleware('auth','khazanah');
|
||||||
Route::get('/laporanscanbarcode',['as'=>'laporanscanbarcode','uses'=>'KhazanahController@LaporanSemakBarcode'])->middleware('auth','khazanah');
|
Route::get('/laporanscanbarcode',['as'=>'laporanscanbarcode','uses'=>'KhazanahController@LaporanSemakBarcode'])->middleware('auth','khazanah');
|
||||||
@@ -190,9 +193,18 @@ Route::get('/penebusankhazanah/{norujukan}',['as'=>'penebusan.khazanah','uses' =
|
|||||||
Route::get('/lelongankhazanah/{norujukan}',['as'=>'lelongan.khazanah','uses' => 'KhazanahController@lelongan'])->middleware('auth','khazanah');
|
Route::get('/lelongankhazanah/{norujukan}',['as'=>'lelongan.khazanah','uses' => 'KhazanahController@lelongan'])->middleware('auth','khazanah');
|
||||||
Route::get('/permohonan',['as'=>'permohonan.index','uses' => 'KhazanahController@PaparanPermohonan'])->middleware('auth','khazanah');
|
Route::get('/permohonan',['as'=>'permohonan.index','uses' => 'KhazanahController@PaparanPermohonan'])->middleware('auth','khazanah');
|
||||||
|
|
||||||
|
Route::get('/notifications',['as'=>'notifications.index','uses'=>'NotificationController@index'])->middleware('auth');
|
||||||
|
Route::post('/notifications/read-all',['as'=>'notifications.read.all','uses'=>'NotificationController@markAllAsRead'])->middleware('auth');
|
||||||
|
Route::post('/notifications/{id}/read',['as'=>'notifications.read','uses'=>'NotificationController@markAsRead'])->middleware('auth');
|
||||||
|
|
||||||
// Pembiayaan Online — PC
|
// Pembiayaan Online — PC
|
||||||
Route::get('/pembiayaan-online/pc',['as'=>'pembiayaan.online.pc','uses'=>'PembiayaanOnlineController@index'])->middleware('auth','khazanah');
|
Route::get('/pembiayaan-online/pc',['as'=>'pembiayaan.online.pc','uses'=>'PembiayaanOnlineController@index'])->middleware('auth','khazanah');
|
||||||
|
Route::get('/pembiayaan-online/pc/reminder',['as'=>'pembiayaan.online.pc.reminder','uses'=>'PembiayaanOnlineController@reminderStatus'])->middleware('auth','khazanah');
|
||||||
Route::put('/pembiayaan-online/pc/lines/{id}',['as'=>'pembiayaan.online.pc.update','uses'=>'PembiayaanOnlineController@updateLine'])->middleware('auth','khazanah');
|
Route::put('/pembiayaan-online/pc/lines/{id}',['as'=>'pembiayaan.online.pc.update','uses'=>'PembiayaanOnlineController@updateLine'])->middleware('auth','khazanah');
|
||||||
|
Route::post('/pembiayaan-online/pc/lines/{id}/verify',['as'=>'pembiayaan.online.pc.verify','uses'=>'PembiayaanOnlineController@verifyLine'])->middleware('auth','khazanah');
|
||||||
|
Route::post('/pembiayaan-online/pc/lines/{id}/unverify',['as'=>'pembiayaan.online.pc.unverify','uses'=>'PembiayaanOnlineController@unverifyLine'])->middleware('auth','khazanah');
|
||||||
|
Route::get('/pembiayaan-online/pc/lines/{id}/bukti-akaun',['as'=>'pembiayaan.online.pc.bukti.akaun','uses'=>'PembiayaanOnlineController@viewBuktiAkaun'])->middleware('auth','khazanah');
|
||||||
|
Route::get('/pembiayaan-online/pc/lines/{id}/sag',['as'=>'pembiayaan.online.pc.sag','uses'=>'PembiayaanOnlineController@viewSag'])->middleware('auth','khazanah');
|
||||||
Route::post('/pembiayaan-online/pc/batches/submit',['as'=>'pembiayaan.online.pc.submit','uses'=>'PembiayaanOnlineController@submitBatch'])->middleware('auth','khazanah');
|
Route::post('/pembiayaan-online/pc/batches/submit',['as'=>'pembiayaan.online.pc.submit','uses'=>'PembiayaanOnlineController@submitBatch'])->middleware('auth','khazanah');
|
||||||
Route::get('/pembiayaan-online/pc/batches/{batchId}',['as'=>'pembiayaan.online.pc.batch','uses'=>'PembiayaanOnlineController@showBatch'])->middleware('auth','khazanah');
|
Route::get('/pembiayaan-online/pc/batches/{batchId}',['as'=>'pembiayaan.online.pc.batch','uses'=>'PembiayaanOnlineController@showBatch'])->middleware('auth','khazanah');
|
||||||
Route::get('/pembiayaan-online/pc/paid',['as'=>'pembiayaan.online.pc.paid','uses'=>'PembiayaanOnlineController@paidIndex'])->middleware('auth','khazanah');
|
Route::get('/pembiayaan-online/pc/paid',['as'=>'pembiayaan.online.pc.paid','uses'=>'PembiayaanOnlineController@paidIndex'])->middleware('auth','khazanah');
|
||||||
@@ -217,6 +229,8 @@ Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/reject',['as'=>'pemb
|
|||||||
Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/approve',['as'=>'pembiayaan.online.operasi.approve.batch','uses'=>'PembiayaanOnlineController@operasiApproveBatch'])->middleware('auth','operasi');
|
Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/approve',['as'=>'pembiayaan.online.operasi.approve.batch','uses'=>'PembiayaanOnlineController@operasiApproveBatch'])->middleware('auth','operasi');
|
||||||
Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/paid',['as'=>'pembiayaan.online.operasi.paid','uses'=>'PembiayaanOnlineController@operasiMarkPaid'])->middleware('auth','operasi');
|
Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/paid',['as'=>'pembiayaan.online.operasi.paid','uses'=>'PembiayaanOnlineController@operasiMarkPaid'])->middleware('auth','operasi');
|
||||||
Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/paid',['as'=>'pembiayaan.online.operasi.paid.batch','uses'=>'PembiayaanOnlineController@operasiMarkPaidBatch'])->middleware('auth','operasi');
|
Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/paid',['as'=>'pembiayaan.online.operasi.paid.batch','uses'=>'PembiayaanOnlineController@operasiMarkPaidBatch'])->middleware('auth','operasi');
|
||||||
|
Route::get('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/bukti-akaun',['as'=>'pembiayaan.online.operasi.bukti.akaun','uses'=>'PembiayaanOnlineController@operasiViewBuktiAkaun'])->middleware('auth','operasi');
|
||||||
|
Route::get('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/sag',['as'=>'pembiayaan.online.operasi.sag','uses'=>'PembiayaanOnlineController@operasiViewSag'])->middleware('auth','operasi');
|
||||||
Route::get('/permohonan/rekod',['as'=>'permohonan.rekod','uses' => 'KhazanahController@RekodPermohonan'])->middleware('auth','khazanah');
|
Route::get('/permohonan/rekod',['as'=>'permohonan.rekod','uses' => 'KhazanahController@RekodPermohonan'])->middleware('auth','khazanah');
|
||||||
Route::post('/permohonan/simpan',['as'=>'permohonan.simpan','uses' => 'KhazanahController@SimpanPermohonan'])->middleware('auth','khazanah');
|
Route::post('/permohonan/simpan',['as'=>'permohonan.simpan','uses' => 'KhazanahController@SimpanPermohonan'])->middleware('auth','khazanah');
|
||||||
Route::get('/permohonan/status/{mohonid}',['as'=>'permohonan.status','uses' => 'KhazanahController@StatusPermohonan'])->middleware('auth','khazanah');
|
Route::get('/permohonan/status/{mohonid}',['as'=>'permohonan.status','uses' => 'KhazanahController@StatusPermohonan'])->middleware('auth','khazanah');
|
||||||
@@ -401,6 +415,7 @@ Route::post('/barcodescanned',['as'=>'barcode.scanned','uses'=>'KhazanahControll
|
|||||||
Route::get('/operasi/kelulusan','OperasiController@kelulusan')->name('operasi.kelulusan')->middleware('auth','operasi');
|
Route::get('/operasi/kelulusan','OperasiController@kelulusan')->name('operasi.kelulusan')->middleware('auth','operasi');
|
||||||
Route::get('/operasi/kelulusan/anggota','OperasiController@kelulusanAnggota')->name('operasi.kelulusananggota')->middleware('auth','operasi');
|
Route::get('/operasi/kelulusan/anggota','OperasiController@kelulusanAnggota')->name('operasi.kelulusananggota')->middleware('auth','operasi');
|
||||||
Route::post('/operasi/createkelulusan',['as'=>'operasi.createkelulusan','uses'=>'OperasiController@createkelulusan'])->middleware('auth','teller');
|
Route::post('/operasi/createkelulusan',['as'=>'operasi.createkelulusan','uses'=>'OperasiController@createkelulusan'])->middleware('auth','teller');
|
||||||
|
Route::post('/operasi/auto-approve-kelulusan',['as'=>'operasi.autoApproveKelulusan','uses'=>'OperasiController@autoApproveKelulusan'])->middleware('auth','teller');
|
||||||
Route::post('/operasi/createkelulusan-by-khazanah',['as'=>'operasi.createkelulusan-by-khazanah','uses'=>'OperasiController@createkelulusanByKhazanah'])->middleware('auth','khazanah');
|
Route::post('/operasi/createkelulusan-by-khazanah',['as'=>'operasi.createkelulusan-by-khazanah','uses'=>'OperasiController@createkelulusanByKhazanah'])->middleware('auth','khazanah');
|
||||||
Route::post('/operasi/createkelulusan-anggota',['as'=>'operasi.createkelulusan-anggota','uses'=>'OperasiController@createkelulusanAnggota'])->middleware('auth','teller');
|
Route::post('/operasi/createkelulusan-anggota',['as'=>'operasi.createkelulusan-anggota','uses'=>'OperasiController@createkelulusanAnggota'])->middleware('auth','teller');
|
||||||
Route::get('/operasi/getkelulusan',['as'=>'operasi.getkelulusan','uses'=>'OperasiController@getkelulusan'])->middleware('auth','teller');
|
Route::get('/operasi/getkelulusan',['as'=>'operasi.getkelulusan','uses'=>'OperasiController@getkelulusan'])->middleware('auth','teller');
|
||||||
|
|||||||
Reference in New Issue
Block a user