Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cde136516d | |||
| 1138e193ae | |||
| 464d3e8dbb | |||
| abccad3219 | |||
| 7ad3fd4f86 | |||
| 713d5a4923 | |||
| b76566a2d6 | |||
| 38f6db2e10 | |||
| f95bdf1214 | |||
| d614677601 | |||
| 7cd21ef610 | |||
| ca2a02e354 | |||
| 76176ed453 | |||
| 17a5bfafdd | |||
| 5f29f064a0 | |||
| 9dae32a462 |
@@ -50,3 +50,5 @@ MYKAD_READER_PORT=17321
|
||||
MYKAD_READER_ENABLED_CAWANGAN=''
|
||||
|
||||
INTERNAL_NOTIFICATION_SECRET=
|
||||
|
||||
LOGVIEWER_PASSWORD=
|
||||
|
||||
@@ -7,6 +7,7 @@ APP_URL=https://ujrah.erahn.com.my
|
||||
API_URL=https://apiujrah.erahn.com.my
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOGVIEWER_PASSWORD="$2y$10$k7eiUyZdm3BruwAaT1gbmelTm.PPgZptOEQT1nlBjyiR84a4KBMlm"
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=192.168.1.216
|
||||
|
||||
+5
-6
@@ -4,17 +4,14 @@ APP_VERSION=v2.2-staging
|
||||
APP_KEY=base64:O1XZDqK4H6+3GdrODgCaLr2l+OoWvgVhYr0GJ1KizW8=
|
||||
APP_DEBUG=true
|
||||
APP_URL=https://staging.erahn.com.my
|
||||
API_URL=https://api-staging.erahn.com.my
|
||||
|
||||
HTTP_PORT=8091
|
||||
MYSQL_PUBLISH_PORT=3309
|
||||
|
||||
API_URL=https://api-staging.erahn.com.my
|
||||
API_URL_KOOP=https://api-staging.erahn.com.my
|
||||
API_URL_PKB=https://api-staging.erahn.com.my
|
||||
API_ARRAHNBID=http://lelong.test/api/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_LEVEL=debug
|
||||
LOGVIEWER_PASSWORD=test123
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mysql
|
||||
@@ -55,4 +52,6 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
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
|
||||
@@ -1,50 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:WRTHcFTq5YARKVdA8YDUzsh9Ue8vD63ivgZgXNNBiGo=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://ujrahkopkb.erahn.com.my
|
||||
API_URL=http://apiujrah-kopkb.erahn.com.my
|
||||
#API_ARRAHNBID=http://lelong.test/api/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=kaunter_erahn
|
||||
DB_USERNAME=spider
|
||||
DB_PASSWORD=G0dz!ll4
|
||||
|
||||
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
|
||||
@@ -1,6 +1,9 @@
|
||||
name: Deploy to Staging
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
image_tag:
|
||||
@@ -18,10 +21,22 @@ jobs:
|
||||
runs-on: host
|
||||
|
||||
steps:
|
||||
- name: Resolve image tag
|
||||
id: resolve
|
||||
run: |
|
||||
set -e
|
||||
if [ "${{ gitea.event_name }}" = "workflow_dispatch" ]; then
|
||||
IMAGE_TAG="${{ inputs.image_tag }}"
|
||||
else
|
||||
IMAGE_TAG="${{ gitea.ref_name }}"
|
||||
fi
|
||||
echo "IMAGE_TAG=${IMAGE_TAG}" >> "$GITHUB_OUTPUT"
|
||||
echo "Deploying image tag: ${IMAGE_TAG}"
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.image_tag }}
|
||||
ref: ${{ steps.resolve.outputs.IMAGE_TAG }}
|
||||
|
||||
- name: Login to Docker registry
|
||||
run: |
|
||||
@@ -33,28 +48,35 @@ jobs:
|
||||
- name: Verify image exists in registry
|
||||
run: |
|
||||
set -e
|
||||
IMAGE_TAG="${{ inputs.image_tag }}"
|
||||
IMAGE_TAG="${{ steps.resolve.outputs.IMAGE_TAG }}"
|
||||
IMAGE="${APP_IMAGE}:${IMAGE_TAG}"
|
||||
|
||||
echo "Checking if image exists: ${IMAGE}"
|
||||
if ! docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then
|
||||
echo "ERROR: Image ${IMAGE} does not exist in registry!"
|
||||
echo "Run the Build Docker Image workflow first."
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ ${IMAGE} found"
|
||||
# Tag pushes build in parallel — wait for the image to appear
|
||||
for i in $(seq 1 30); do
|
||||
if docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then
|
||||
echo "✓ ${IMAGE} found"
|
||||
exit 0
|
||||
fi
|
||||
echo "Image not ready yet (attempt ${i}/30), waiting 20s..."
|
||||
sleep 20
|
||||
done
|
||||
|
||||
echo "ERROR: Image ${IMAGE} does not exist in registry after waiting!"
|
||||
echo "Run the Build Docker Image workflow first."
|
||||
exit 1
|
||||
|
||||
- name: Pull Docker image
|
||||
run: |
|
||||
set -e
|
||||
IMAGE_TAG="${{ inputs.image_tag }}"
|
||||
IMAGE_TAG="${{ steps.resolve.outputs.IMAGE_TAG }}"
|
||||
docker pull "${APP_IMAGE}:${IMAGE_TAG}"
|
||||
echo "✓ Image pulled successfully"
|
||||
|
||||
- name: Sync compose file and deploy
|
||||
run: |
|
||||
set -e
|
||||
IMAGE_TAG="${{ inputs.image_tag }}"
|
||||
IMAGE_TAG="${{ steps.resolve.outputs.IMAGE_TAG }}"
|
||||
|
||||
mkdir -p "${DEPLOY_DIR}/docker/nginx" "${DEPLOY_DIR}/public"
|
||||
cp docker-compose.staging.yml "${DEPLOY_DIR}/docker-compose.yml"
|
||||
@@ -62,15 +84,12 @@ jobs:
|
||||
find "${DEPLOY_DIR}/public" -mindepth 1 -delete
|
||||
cp -R public/. "${DEPLOY_DIR}/public/"
|
||||
|
||||
if [ ! -f "${DEPLOY_DIR}/.env.staging" ]; then
|
||||
if [ -f .env.staging ]; then
|
||||
cp .env.staging "${DEPLOY_DIR}/.env.staging"
|
||||
echo "Copied .env.staging from repo (first deploy). Edit ${DEPLOY_DIR}/.env.staging on the server if needed."
|
||||
else
|
||||
echo "ERROR: ${DEPLOY_DIR}/.env.staging is missing on the server"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f .env.staging ]; then
|
||||
echo "ERROR: .env.staging is missing in the repository"
|
||||
exit 1
|
||||
fi
|
||||
cp .env.staging "${DEPLOY_DIR}/.env.staging"
|
||||
echo "✓ Synced .env.staging from repo"
|
||||
|
||||
cd "${DEPLOY_DIR}"
|
||||
|
||||
|
||||
@@ -5,15 +5,12 @@ namespace App\Http\Controllers\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
use App\Dashboard;
|
||||
use App\User;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -144,25 +141,26 @@ class LoginController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
public function logout(){
|
||||
$current = Carbon::now();
|
||||
$current = new Carbon();
|
||||
$current = $current->toDateString();
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$auth_user = Auth::guard('web')->user();
|
||||
Auth::logout();
|
||||
Session::flush();
|
||||
$session = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/logoutsession/' . $auth_user['cawangan'], [
|
||||
'id' => $auth_user['id'],
|
||||
'nama' => $auth_user['name'],
|
||||
'nokp' => $auth_user['no_kp'],
|
||||
'email' => $auth_user['email'],
|
||||
'taraf' => $auth_user['role_harian'],
|
||||
'tarikh' => $current,
|
||||
|
||||
|
||||
]);
|
||||
Auth::guard('web')->logout();
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return Redirect::to('/');
|
||||
if ($auth_user) {
|
||||
Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/logoutsession/' . $auth_user['cawangan'], [
|
||||
'id' => $auth_user['id'],
|
||||
'nama' => $auth_user['name'],
|
||||
'nokp' => $auth_user['no_kp'],
|
||||
'email' => $auth_user['email'],
|
||||
'taraf' => $auth_user['role_harian'],
|
||||
'tarikh' => now()->toDateString(),
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
public function GetRolesHarian(Request $request, $kodcaw){
|
||||
|
||||
@@ -298,7 +298,7 @@ class GadaianController extends Controller
|
||||
}
|
||||
|
||||
if ($caraTerima === 'ONLINE' && !$this->hasMatchingBorangOnlinePrint($request)) {
|
||||
return redirect()->back()->with('error', 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.');
|
||||
return $this->gadaiStoreResult($request, false, 'Sila cetak borang pengesahan pelanggan sebelum tekan Terima.');
|
||||
}
|
||||
|
||||
//$total_nilai_marhun = $request->total_nilai_marhun;
|
||||
@@ -320,6 +320,27 @@ class GadaianController extends Controller
|
||||
$keuntungan12bulan = $keuntungan_sebln * 12;
|
||||
|
||||
$hargajualan = $request->pinjaman + $keuntungan12bulan;
|
||||
|
||||
// BSAS commodity order must succeed before finalizing gadai.
|
||||
$bsas = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->timeout(60)
|
||||
->post(config('api.url') . '/api/komuditi/bsas/order', [
|
||||
'norujukan' => $request->norujukan_gadai,
|
||||
'kodcaw' => $auth_user['cawangan'],
|
||||
'pinjaman' => round((float) $request->pinjaman, 2),
|
||||
'hargajualan' => round((float) $hargajualan, 2),
|
||||
'nama_pelanggan' => $request->nama_pelanggan ?: $request->nama_akaun,
|
||||
'teller' => $auth_user['name'],
|
||||
]);
|
||||
|
||||
if (!$bsas->successful()) {
|
||||
$body = $bsas->json();
|
||||
$msg = is_array($body) && isset($body['message'])
|
||||
? $body['message']
|
||||
: 'Gagal pembelian komoditi BSAS. Sila cuba lagi.';
|
||||
return $this->gadaiStoreResult($request, false, $msg);
|
||||
}
|
||||
|
||||
//Log::info('DEBUG NOKP:' . $request->nokp);
|
||||
$gadai = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/gadai/norujukan/' . $auth_user['cawangan'] . '/' . $request->norujukan_gadai, [
|
||||
'kodcaw' => $auth_user['cawangan'],
|
||||
@@ -344,14 +365,6 @@ class GadaianController extends Controller
|
||||
'rebate' => $this->parseMoney($request->rebate),
|
||||
])->json();
|
||||
|
||||
|
||||
$komuditi = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/komuditi/transaksi', [
|
||||
'unit_komuditi' => round($request->pinjaman, 2),
|
||||
'norujukan' => $request->norujukan_gadai,
|
||||
'kodcaw' => $auth_user['cawangan'],
|
||||
'teller' => $auth_user['name']
|
||||
]);
|
||||
|
||||
if ($caraTerima === 'ONLINE') {
|
||||
$online = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->asForm()
|
||||
@@ -374,7 +387,7 @@ class GadaianController extends Controller
|
||||
$msg = is_array($body) && isset($body['message'])
|
||||
? $body['message']
|
||||
: 'Gagal daftar pembiayaan online. Sila cuba lagi.';
|
||||
return redirect()->back()->with('error', $msg);
|
||||
return $this->gadaiStoreResult($request, false, $msg);
|
||||
}
|
||||
|
||||
$this->notifyPcPembiayaanOnlinePending($auth_user, $request, $pinjamanAmt);
|
||||
@@ -392,6 +405,33 @@ class GadaianController extends Controller
|
||||
$request->session()->flash('message', 'Gadai berjaya. Pembiayaan online menunggu semakan PC.');
|
||||
}
|
||||
|
||||
return $this->gadaiStoreResult($request, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON for AJAX Terima (BSAS progress UI); normal redirect otherwise.
|
||||
*/
|
||||
protected function gadaiStoreResult(Request $request, bool $ok, string $message = null)
|
||||
{
|
||||
if ($request->ajax() || $request->wantsJson()) {
|
||||
if (!$ok) {
|
||||
return response()->json([
|
||||
'ok' => false,
|
||||
'message' => $message ?: 'Gadai tidak berjaya.',
|
||||
], 422);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'message' => $message ?: 'Gadai berjaya.',
|
||||
'redirect' => route('customer_info'),
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$ok) {
|
||||
return redirect()->back()->with('error', $message ?: 'Gadai tidak berjaya.');
|
||||
}
|
||||
|
||||
return redirect()->route('customer_info');
|
||||
}
|
||||
|
||||
@@ -671,16 +711,38 @@ class GadaianController extends Controller
|
||||
// $pembayaran_segera = "https://spare.arrahn.com.my/pembayaransegera";
|
||||
$pembayaran_segera = "https://pay.arrahn.com.my";
|
||||
|
||||
$komoditi = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get($api_url . '/api/komuditi/check')
|
||||
->json();
|
||||
$product = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get($api_url . '/api/komuditi/description', ['kodproduk' => $komoditi['kodproduct']])
|
||||
->json();
|
||||
$kuantiti = $gadai_detail['pinjaman'] / $komoditi['nilai'];
|
||||
$bsasSag = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get($api_url . '/api/komuditi/bsas/order/norujukan/' . urlencode($norujukan));
|
||||
|
||||
$komoditi = [];
|
||||
$product = [];
|
||||
$kuantiti = 0;
|
||||
|
||||
if ($bsasSag->successful() && is_array($bsasSag->json())) {
|
||||
$bsasPayload = $bsasSag->json();
|
||||
$komoditi = $bsasPayload['komoditi'] ?? [];
|
||||
$product = $bsasPayload['product'] ?? [];
|
||||
$kuantiti = (float) ($bsasPayload['kuantiti'] ?? 0);
|
||||
}
|
||||
|
||||
if (!is_array($komoditi)) {
|
||||
$komoditi = [];
|
||||
}
|
||||
if (!is_array($product)) {
|
||||
$product = [
|
||||
'product_code' => $komoditi['kodproduct'] ?? '',
|
||||
'kodproduk' => $komoditi['kodproduct'] ?? '',
|
||||
'description' => '',
|
||||
'unit' => 'TAN',
|
||||
];
|
||||
}
|
||||
|
||||
if ($gadai_detail['tagbaru'] == 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'));
|
||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get($api_url . '/api/cawangan/' . $kodcaw)->json();
|
||||
$pembiayaanOnlineEnabled = !empty(($cawangan_info['features'] ?? [])['pembiayaan_online']);
|
||||
|
||||
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'))->with('pembiayaanOnlineEnabled', $pembiayaanOnlineEnabled);
|
||||
} else {
|
||||
return view('print.sag', compact('gadai_detail', 'customer_detail', 'marhun_detail', 'cawangan_detail', 'api_url', 'pembayaran_segera', 'auth_username', 'mutu', 'kakitangan'));
|
||||
}
|
||||
|
||||
@@ -55,4 +55,274 @@ class KomuditiController extends Controller
|
||||
|
||||
return redirect()->route('komuditi');
|
||||
}
|
||||
|
||||
/**
|
||||
* Khazanah branch list of BSAS commodity orders.
|
||||
*/
|
||||
public function khazanahBsas()
|
||||
{
|
||||
$auth_user = Auth::user();
|
||||
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get(config('api.url') . '/api/cawangan/' . $auth_user['cawangan'])
|
||||
->json();
|
||||
|
||||
return view('homepage.khazanah.bsas_komoditi', compact('cawangan_info'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy BSAS eCert layout preview (bid, OTC, STB, then one commodity schedule).
|
||||
*/
|
||||
public function previewBsasEcert()
|
||||
{
|
||||
$line = [
|
||||
['SUPPLIER' => 'FGV TRADING SDN BHD', 'VOLUME' => '0.75276406'],
|
||||
];
|
||||
|
||||
return view('print.bsas_ecert', $this->presentBsasCertificates([
|
||||
'e_cert_no' => 'CPO21OCT26-0000031-000',
|
||||
'serial_number' => '1',
|
||||
'otc_counter_party' => 'ALI BIN ABU',
|
||||
'otc_murabaha_value' => '3,814.40',
|
||||
'product_code' => 'CPO-MSIA-09',
|
||||
'bid_ecert' => [
|
||||
'ECERTNO' => 'CPO21OCT26-0000031-000',
|
||||
'BUYER' => 'KOPERASI PERMODALAN KELANTAN BERHAD',
|
||||
'OWNER' => 'KOPERASI PERMODALAN KELANTAN BERHAD',
|
||||
'BIDNO' => '8',
|
||||
'TOTALVALUE' => '3,200.00',
|
||||
'CURRENCY' => 'MYR',
|
||||
'PRICE' => '4,251.00',
|
||||
'PRICE_MYR_EQUIVALENT' => '4,251.00',
|
||||
'PURCHASETIMEDATE' => '15:11:53.316 21 Oct 2026',
|
||||
'VALUEDATE' => '21 Oct 2026',
|
||||
'PNAME' => 'CPO-MSIA-09',
|
||||
'PVOLUME' => '0.75276406',
|
||||
'LINE' => $line,
|
||||
],
|
||||
'otc_ecert' => [
|
||||
'ECERTNO' => 'CPO21OCT26-0000031-000',
|
||||
'SELLER' => 'KOPERASI PERMODALAN KELANTAN BERHAD',
|
||||
'BUYER' => 'ALI BIN ABU',
|
||||
'REPORTINGTIMEDATE' => '15:11:53.320 21 Oct 2026',
|
||||
'VALUEDATE' => '21 Oct 2026',
|
||||
'PNAME' => 'CPO-MSIA-09',
|
||||
'PVOLUME' => '0.75276406',
|
||||
'CURRENCY' => 'MYR',
|
||||
'PRICE' => '4,251.00',
|
||||
'PRICE_MYR_EQUIVALENT' => '4,251.00',
|
||||
'TOTALVALUE' => '3,200.00',
|
||||
'MURABAHAVALUE' => '3,814.40',
|
||||
'LINE' => $line,
|
||||
],
|
||||
'stb_ecert' => [
|
||||
'ECERTNO' => 'CPO21OCT26-0000031-000',
|
||||
'SELLER' => 'ALI BIN ABU',
|
||||
'BUYER' => 'BURSA MALAYSIA ISLAMIC SERVICES',
|
||||
'TOTALVALUE' => '3,200.00',
|
||||
'CURRENCY' => 'MYR',
|
||||
'PRICE' => '4,251.00',
|
||||
'PRICE_MYR_EQUIVALENT' => '4,251.00',
|
||||
'SELLINGTIMEDATE' => '15:11:53.325 21 Oct 2026',
|
||||
'VALUEDATE' => '21 Oct 2026',
|
||||
'PNAME' => 'CPO-MSIA-09',
|
||||
'PVOLUME' => '0.75276406',
|
||||
'LINE' => $line,
|
||||
],
|
||||
], true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Live BSAS eCerts from stored bid, OTC and STB payloads.
|
||||
*/
|
||||
public function showBsasEcert($uuid)
|
||||
{
|
||||
$response = Http::withOptions(['verify' => config('app.api_verify')])
|
||||
->get(config('api.url') . '/api/komuditi/bsas/order/' . urlencode($uuid) . '/ecert');
|
||||
|
||||
if ($response->status() === 404) {
|
||||
abort(404, $response->json('message') ?: 'eCert tidak dijumpai.');
|
||||
}
|
||||
|
||||
if (!$response->successful()) {
|
||||
abort(502, 'Gagal memuatkan eCert BSAS.');
|
||||
}
|
||||
|
||||
$payload = $response->json();
|
||||
if (!is_array($payload)) {
|
||||
abort(502, 'Gagal memuatkan eCert BSAS.');
|
||||
}
|
||||
|
||||
$presented = $this->presentBsasCertificates($payload, false);
|
||||
if ($presented['certificates'] === []) {
|
||||
abort(404, 'eCert belum tersedia untuk order ini.');
|
||||
}
|
||||
|
||||
return view('print.bsas_ecert', $presented);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bid, OTC and STB pages, plus one shared commodity schedule.
|
||||
*/
|
||||
protected function presentBsasCertificates(array $payload, bool $isDummy): array
|
||||
{
|
||||
$certificates = [];
|
||||
|
||||
$bid = $payload['bid_ecert'] ?? null;
|
||||
if (is_array($bid) && $bid !== []) {
|
||||
$certificates[] = $this->mapBidCertificate($bid, $payload);
|
||||
}
|
||||
|
||||
$otc = $payload['otc_ecert'] ?? null;
|
||||
if (is_array($otc) && $otc !== []) {
|
||||
$certificates[] = $this->mapOtcCertificate($otc, $payload);
|
||||
}
|
||||
|
||||
$stb = $payload['stb_ecert'] ?? null;
|
||||
if (is_array($stb) && $stb !== []) {
|
||||
$certificates[] = $this->mapStbCertificate($stb, $payload);
|
||||
}
|
||||
|
||||
$scheduleSource = [];
|
||||
if (is_array($otc) && $otc !== []) {
|
||||
$scheduleSource = $otc;
|
||||
} elseif (is_array($bid) && $bid !== []) {
|
||||
$scheduleSource = $bid;
|
||||
} elseif (is_array($stb) && $stb !== []) {
|
||||
$scheduleSource = $stb;
|
||||
}
|
||||
|
||||
$ecertNo = $scheduleSource['ECERTNO'] ?? ($payload['e_cert_no'] ?? '-');
|
||||
|
||||
return [
|
||||
'certificates' => $certificates,
|
||||
'ecert_no' => $ecertNo,
|
||||
'lines' => $this->mapBsasLines($scheduleSource),
|
||||
'isDummy' => $isDummy,
|
||||
];
|
||||
}
|
||||
|
||||
protected function mapBidCertificate(array $ecert, array $orderMeta): array
|
||||
{
|
||||
[$time, $date] = $this->splitBsasDateTime((string) ($ecert['PURCHASETIMEDATE'] ?? ''));
|
||||
|
||||
return $this->certificatePage(
|
||||
'Certificate of Purchase',
|
||||
'This is to certify that the following bid transaction has been executed<br>through the Bursa Suq Al-Sila\' in accordance with the<br>Rules of Bursa Suq Al-Sila\'.',
|
||||
$ecert,
|
||||
$orderMeta,
|
||||
array_merge([
|
||||
['label' => 'Buyer', 'value' => $ecert['BUYER'] ?? '-'],
|
||||
['label' => 'Owner', 'value' => $ecert['OWNER'] ?? '-'],
|
||||
['label' => 'Bid No', 'value' => $ecert['BIDNO'] ?? ($orderMeta['serial_number'] ?? '-')],
|
||||
['label' => 'Purchase Time / Date', 'value' => $time . ' / ' . $date],
|
||||
], $this->commodityDetailRows($ecert, $orderMeta))
|
||||
);
|
||||
}
|
||||
|
||||
protected function mapOtcCertificate(array $ecert, array $orderMeta): array
|
||||
{
|
||||
[$time, $date] = $this->splitBsasDateTime((string) ($ecert['REPORTINGTIMEDATE'] ?? ''));
|
||||
|
||||
$page = $this->certificatePage(
|
||||
'Certificate of Murabahah',
|
||||
'This is to certify that the following transaction has been executed<br>through the Bursa Suq Al-Sila\' in accordance with the<br>Rules of Bursa Suq Al-Sila\'.',
|
||||
$ecert,
|
||||
$orderMeta,
|
||||
array_merge([
|
||||
['label' => 'Seller', 'value' => $ecert['SELLER'] ?? 'KOPERASI PERMODALAN KELANTAN BERHAD'],
|
||||
['label' => 'Buyer', 'value' => $ecert['BUYER'] ?? ($orderMeta['otc_counter_party'] ?? '-')],
|
||||
['label' => 'Bid No', 'value' => $orderMeta['serial_number'] ?? '1'],
|
||||
['label' => 'Reporting Time / Date', 'value' => $time . ' / ' . $date],
|
||||
], $this->commodityDetailRows($ecert, $orderMeta), [
|
||||
['label' => 'Transaction Type', 'value' => '-'],
|
||||
])
|
||||
);
|
||||
|
||||
$page['show_murabaha'] = true;
|
||||
$page['murabaha'] = $ecert['MURABAHAVALUE'] ?? ($orderMeta['otc_murabaha_value'] ?? '-');
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
protected function mapStbCertificate(array $ecert, array $orderMeta): array
|
||||
{
|
||||
[$time, $date] = $this->splitBsasDateTime((string) ($ecert['SELLINGTIMEDATE'] ?? ''));
|
||||
|
||||
return $this->certificatePage(
|
||||
'Certificate of Sale',
|
||||
'This is to certify that the following sale transaction has been executed<br>through the Bursa Suq Al-Sila\' in accordance with the<br>Rules of Bursa Suq Al-Sila\'.',
|
||||
$ecert,
|
||||
$orderMeta,
|
||||
array_merge([
|
||||
['label' => 'Seller', 'value' => $ecert['SELLER'] ?? ($orderMeta['otc_counter_party'] ?? '-')],
|
||||
['label' => 'Buyer', 'value' => $ecert['BUYER'] ?? '-'],
|
||||
['label' => 'Selling Time / Date', 'value' => $time . ' / ' . $date],
|
||||
], $this->commodityDetailRows($ecert, $orderMeta))
|
||||
);
|
||||
}
|
||||
|
||||
protected function certificatePage(string $title, string $statement, array $ecert, array $orderMeta, array $rows): array
|
||||
{
|
||||
return [
|
||||
'title' => $title,
|
||||
'statement' => $statement,
|
||||
'ecert_no' => $ecert['ECERTNO'] ?? ($orderMeta['e_cert_no'] ?? '-'),
|
||||
'currency' => $ecert['CURRENCY'] ?? 'MYR',
|
||||
'rows' => $rows,
|
||||
'show_murabaha' => false,
|
||||
'murabaha' => null,
|
||||
];
|
||||
}
|
||||
|
||||
protected function commodityDetailRows(array $ecert, array $orderMeta): array
|
||||
{
|
||||
return [
|
||||
['label' => 'Value Date', 'value' => isset($ecert['VALUEDATE']) ? strtoupper((string) $ecert['VALUEDATE']) : '-'],
|
||||
['label' => 'Product Code / Description', 'value' => $ecert['PNAME'] ?? ($orderMeta['product_code'] ?? '-')],
|
||||
['label' => 'Unit', 'value' => 'Tonnage'],
|
||||
['label' => 'Volume', 'value' => $ecert['PVOLUME'] ?? '-'],
|
||||
['label' => 'Currency', 'value' => $ecert['CURRENCY'] ?? 'MYR'],
|
||||
['label' => 'Price (MYR)', 'value' => $ecert['PRICE'] ?? '-'],
|
||||
['label' => 'Price (MYR Equivalent)', 'value' => $ecert['PRICE_MYR_EQUIVALENT'] ?? ($ecert['PRICE'] ?? '-')],
|
||||
['label' => 'Value', 'value' => $ecert['TOTALVALUE'] ?? '-'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function mapBsasLines(array $ecert): array
|
||||
{
|
||||
$lines = [];
|
||||
foreach (($ecert['LINE'] ?? []) as $line) {
|
||||
if (!is_array($line)) {
|
||||
continue;
|
||||
}
|
||||
$lines[] = [
|
||||
'supplier' => $line['SUPPLIER'] ?? '-',
|
||||
'volume' => $line['VOLUME'] ?? ($ecert['PVOLUME'] ?? '-'),
|
||||
];
|
||||
}
|
||||
|
||||
if ($lines === []) {
|
||||
$lines[] = [
|
||||
'supplier' => '-',
|
||||
'volume' => $ecert['PVOLUME'] ?? '-',
|
||||
];
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
protected function splitBsasDateTime(string $value): array
|
||||
{
|
||||
$value = trim($value);
|
||||
if ($value === '') {
|
||||
return ['-', '-'];
|
||||
}
|
||||
|
||||
$parts = explode(' ', $value, 2);
|
||||
|
||||
return [
|
||||
$parts[0] ?? '-',
|
||||
isset($parts[1]) ? strtoupper($parts[1]) : '-',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,6 @@ class PembiayaanOnlineController extends Controller
|
||||
'kodbank' => $request->input('kodbank'),
|
||||
'noakaun' => $request->input('noakaun'),
|
||||
'nama_bank' => $request->input('nama_bank'),
|
||||
'nama_akaun' => $request->input('nama_akaun'),
|
||||
'nota' => $request->input('nota'),
|
||||
'update_customer_bank' => true,
|
||||
];
|
||||
@@ -174,6 +173,19 @@ class PembiayaanOnlineController extends Controller
|
||||
$payload['bukti_akaun_type'] = $file->getMimeType() ?: 'application/octet-stream';
|
||||
}
|
||||
|
||||
if ($request->hasFile('borang')) {
|
||||
$file = $request->file('borang');
|
||||
if (!$file->isValid()) {
|
||||
return redirect()->back()->with('error', 'Fail borang pengesahan tidak sah.');
|
||||
}
|
||||
if ($file->getSize() > 4 * 1024 * 1024) {
|
||||
return redirect()->back()->with('error', 'Saiz fail maksimum 4MB.');
|
||||
}
|
||||
$payload['borang_data'] = base64_encode(file_get_contents($file->getRealPath()));
|
||||
$payload['borang_filename'] = $file->getClientOriginalName();
|
||||
$payload['borang_type'] = $file->getMimeType() ?: 'application/octet-stream';
|
||||
}
|
||||
|
||||
$res = $this->api()
|
||||
->asForm()
|
||||
->put($api_url . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id, $payload);
|
||||
@@ -394,6 +406,22 @@ class PembiayaanOnlineController extends Controller
|
||||
return $this->streamBase64File($file, 'slip-bank-' . $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* PC: view uploaded Borang Pengesahan Penerimaan Pembiayaan Secara Atas Talian.
|
||||
*/
|
||||
public function viewBorang($id)
|
||||
{
|
||||
$this->abortUnlessPembiayaanOnline();
|
||||
return $this->streamLineFile(
|
||||
$this->kodcaw(),
|
||||
$id,
|
||||
'/borang',
|
||||
'Borang pengesahan tidak dijumpai.',
|
||||
'Fail borang pengesahan kosong.',
|
||||
'borang-pengesahan-' . $id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* PC: view SAG for a queue line (does not mark SAG as printed).
|
||||
*/
|
||||
@@ -426,6 +454,21 @@ class PembiayaanOnlineController extends Controller
|
||||
return $this->streamBase64File($file, 'slip-bank-' . $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operasi: view uploaded Borang Pengesahan Penerimaan Pembiayaan Secara Atas Talian.
|
||||
*/
|
||||
public function operasiViewBorang($kodcaw, $id)
|
||||
{
|
||||
return $this->streamLineFile(
|
||||
$kodcaw,
|
||||
$id,
|
||||
'/borang',
|
||||
'Borang pengesahan tidak dijumpai.',
|
||||
'Fail borang pengesahan kosong.',
|
||||
'borang-pengesahan-' . $id
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operasi: view SAG for a batch line.
|
||||
*/
|
||||
@@ -434,6 +477,26 @@ class PembiayaanOnlineController extends Controller
|
||||
return $this->renderLineSag($kodcaw, $id);
|
||||
}
|
||||
|
||||
protected function streamLineFile($kodcaw, $id, $path, $missingMessage, $emptyMessage, $fallbackName)
|
||||
{
|
||||
$res = $this->api()
|
||||
->get(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/lines/' . $id . $path);
|
||||
|
||||
if (!$res->successful()) {
|
||||
$body = $res->json();
|
||||
$msg = is_array($body) && isset($body['message']) ? $body['message'] : $missingMessage;
|
||||
return redirect()->back()->with('error', $msg);
|
||||
}
|
||||
|
||||
$payload = $res->json();
|
||||
$file = $payload['file'] ?? null;
|
||||
if (!$file || empty($file['data'])) {
|
||||
return redirect()->back()->with('error', $emptyMessage);
|
||||
}
|
||||
|
||||
return $this->streamBase64File($file, $fallbackName);
|
||||
}
|
||||
|
||||
protected function streamBase64File(array $file, $fallbackName)
|
||||
{
|
||||
$raw = $file['data'];
|
||||
@@ -522,17 +585,43 @@ class PembiayaanOnlineController extends Controller
|
||||
|
||||
$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();
|
||||
// Prefer per-Terima BSAS order; fall back to legacy daily KomuditiPurchase.
|
||||
$bsasSag = $this->api()
|
||||
->get($api_url . '/api/komuditi/bsas/order/norujukan/' . urlencode($norujukan));
|
||||
|
||||
$nilai = is_array($komoditi) ? (float) ($komoditi['nilai'] ?? 0) : 0;
|
||||
$kuantiti = $nilai > 0 ? ((float) ($gadai_detail['pinjaman'] ?? 0) / $nilai) : 0;
|
||||
if ($bsasSag->successful() && is_array($bsasSag->json())) {
|
||||
$bsasPayload = $bsasSag->json();
|
||||
$komoditi = $bsasPayload['komoditi'] ?? [];
|
||||
$product = $bsasPayload['product'] ?? [];
|
||||
$kuantiti = (float) ($bsasPayload['kuantiti'] ?? 0);
|
||||
} else {
|
||||
$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 (!is_array($komoditi)) {
|
||||
$komoditi = [];
|
||||
}
|
||||
if (!is_array($product)) {
|
||||
$product = [
|
||||
'kodproduk' => $komoditi['kodproduct'] ?? '',
|
||||
'description' => '',
|
||||
'unit' => 'TAN',
|
||||
];
|
||||
}
|
||||
|
||||
if (($gadai_detail['tagbaru'] ?? 0) == 1) {
|
||||
$cawangan_info = $this->api()
|
||||
->get($api_url . '/api/cawangan/' . $kodcaw)->json();
|
||||
$pembiayaanOnlineEnabled = !empty(($cawangan_info['features'] ?? [])['pembiayaan_online']);
|
||||
|
||||
return view('print.sag_ujrah_3', compact(
|
||||
'komoditi',
|
||||
'product',
|
||||
@@ -547,7 +636,7 @@ class PembiayaanOnlineController extends Controller
|
||||
'mutu',
|
||||
'kadar_ujrah',
|
||||
'kakitangan'
|
||||
));
|
||||
))->with('pembiayaanOnlineEnabled', $pembiayaanOnlineEnabled);
|
||||
}
|
||||
|
||||
return view('print.sag', compact(
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class LogViewerPassword
|
||||
{
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$passwordHash = config('logviewer.password');
|
||||
|
||||
if (!is_string($passwordHash) || $passwordHash === '') {
|
||||
return response('Akses log belum dikonfigurasi.', 503)
|
||||
->header('Cache-Control', 'no-store');
|
||||
}
|
||||
|
||||
$provided = $request->getPassword();
|
||||
if ($request->getUser() !== 'logviewer' || !is_string($provided) ||
|
||||
!password_verify($provided, $passwordHash)) {
|
||||
return response('Kata laluan diperlukan untuk mengakses log.', 401, [
|
||||
'WWW-Authenticate' => 'Basic realm="Log Viewer", charset="UTF-8"',
|
||||
'Cache-Control' => 'no-store',
|
||||
]);
|
||||
}
|
||||
|
||||
$response = $next($request);
|
||||
$response->headers->set('Cache-Control', 'no-store');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,12 @@ class RoleAccess
|
||||
return $next($request);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'masteradmin':
|
||||
if ($userRole == 'masteradmin') {
|
||||
return $next($request);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'penilai':
|
||||
if ($userRole == 'penilai') {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'password' => env('LOGVIEWER_PASSWORD'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pattern and storage path settings
|
||||
|
||||
+3
-10
@@ -5,6 +5,8 @@ services:
|
||||
dockerfile: docker/php/Dockerfile
|
||||
target: development
|
||||
working_dir: /var/www/html
|
||||
ports:
|
||||
- "8081:8000"
|
||||
volumes:
|
||||
- ./:/var/www/html:cached
|
||||
environment:
|
||||
@@ -15,16 +17,7 @@ services:
|
||||
- "host.docker.internal:host-gateway"
|
||||
depends_on:
|
||||
- mysql
|
||||
|
||||
web:
|
||||
image: nginx:1.25-alpine
|
||||
ports:
|
||||
- "8081:80"
|
||||
volumes:
|
||||
- ./:/var/www/html:cached
|
||||
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
depends_on:
|
||||
- app
|
||||
command: ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]
|
||||
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
|
||||
@@ -2,7 +2,14 @@ FROM php:7.4-fpm AS base
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
RUN apt-get update \
|
||||
# php:7.4-fpm is Debian 11 (bullseye); after LTS end, packages live on archive.debian.org
|
||||
RUN sed -i \
|
||||
-e 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g' \
|
||||
-e 's|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' \
|
||||
-e 's|http://deb.debian.org/debian-security|http://archive.debian.org/debian-security|g' \
|
||||
/etc/apt/sources.list \
|
||||
&& printf 'Acquire::Check-Valid-Until "false";\n' > /etc/apt/apt.conf.d/99no-check-valid-until \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
pkg-config \
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://kaunterv2.localhost
|
||||
API_URL=http://apiv2.localhost
|
||||
API_ARRAHNBID=http://lelong.localhost/api/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=database_zone2
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=kaunterpkb
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=secret
|
||||
|
||||
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
|
||||
@@ -1,50 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://kaunterv2.localhost
|
||||
API_URL=http://apiv2.kgmk.localhost
|
||||
API_ARRAHNBID=http://lelong.localhost/api/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=database_zone_franchise
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=kaunter_koopguru
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=secret
|
||||
|
||||
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
|
||||
@@ -1,50 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:FFRogE6mJj8FaDSSHl/KpXpzqi2M+P4plxVSRgVM8JI=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://kaunterv2.localhost
|
||||
API_URL=http://apiv2.krk.localhost
|
||||
API_ARRAHNBID=http://lelong.localhost/api/
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=database_zone_franchise
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=kaunter_krk
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=secret
|
||||
|
||||
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
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1136" viewBox="0 0 1600 1136">
|
||||
<title>Vectorized Arabic calligraphy logo</title>
|
||||
<path d="M 379,572 L 385,578 L 403,585 L 418,593 L 423,594 L 429,598 L 415,588 Z M 949,551 L 945,547 L 939,546 L 933,550 L 928,557 L 851,719 L 814,784 L 784,827 L 754,862 L 720,894 L 690,917 L 647,944 L 595,969 L 543,987 L 504,996 L 453,1002 L 406,1002 L 374,999 L 344,994 L 312,986 L 274,973 L 249,962 L 227,950 L 255,967 L 267,972 L 268,974 L 322,995 L 376,1008 L 417,1013 L 438,1014 L 499,1011 L 543,1003 L 572,995 L 606,983 L 660,958 L 708,928 L 748,896 L 785,858 L 815,819 L 836,787 L 864,737 L 895,674 L 930,597 L 943,571 L 950,563 Z M 292,508 L 288,515 L 247,563 L 256,571 L 260,573 L 266,572 L 303,528 L 303,519 Z M 989,450 L 969,456 L 945,459 L 917,458 L 900,451 L 894,451 L 888,454 L 880,462 L 869,476 L 842,504 L 802,536 L 765,557 L 741,567 L 722,573 L 676,582 L 630,584 L 600,582 L 573,578 L 525,566 L 523,567 L 520,573 L 520,585 L 530,614 L 538,654 L 538,687 L 535,707 L 529,729 L 516,757 L 498,782 L 472,807 L 429,836 L 393,854 L 358,867 L 312,878 L 287,881 L 235,880 L 194,871 L 162,857 L 179,868 L 214,883 L 238,889 L 273,893 L 308,892 L 347,886 L 386,875 L 418,862 L 440,851 L 465,836 L 500,809 L 523,783 L 531,771 L 541,751 L 548,730 L 552,710 L 553,666 L 545,627 L 535,596 L 535,590 L 540,581 L 543,579 L 551,579 L 578,587 L 607,592 L 638,595 L 675,595 L 697,593 L 741,584 L 777,571 L 804,557 L 827,542 L 853,521 L 881,493 L 893,478 L 907,465 L 918,463 L 935,469 L 962,470 Z M 1071,446 L 1064,445 L 1063,450 L 1057,461 L 1047,471 L 1035,480 L 1011,505 L 1001,520 L 993,536 L 987,555 L 984,576 L 984,594 L 987,613 L 991,625 L 999,640 L 1007,650 L 1018,659 L 1010,648 L 1009,643 L 1007,641 L 1000,615 L 999,598 L 1003,566 L 1010,546 L 1023,523 L 1046,497 L 1069,478 L 1076,468 L 1078,462 L 1078,454 L 1076,450 Z M 1247,419 L 1238,416 L 1233,418 L 1228,423 L 1200,481 L 1191,494 L 1179,507 L 1170,531 L 1170,536 L 1177,534 L 1189,525 L 1203,511 L 1217,492 L 1241,441 L 1245,435 L 1252,430 L 1252,426 Z M 1403,405 L 1394,406 L 1388,412 L 1383,423 L 1378,473 L 1374,491 L 1369,505 L 1367,523 L 1363,536 L 1362,545 L 1365,545 L 1375,533 L 1387,511 L 1395,475 L 1396,451 L 1399,435 L 1405,424 L 1409,420 L 1415,418 L 1411,411 Z M 1474,363 L 1486,379 L 1493,393 L 1500,416 L 1506,464 L 1506,502 L 1502,540 L 1495,575 L 1482,617 L 1470,646 L 1443,696 L 1422,727 L 1390,766 L 1331,825 L 1223,928 L 1149,1004 L 1136,1027 L 1132,1037 L 1132,1047 L 1137,1046 L 1177,1003 L 1251,929 L 1329,855 L 1401,784 L 1426,755 L 1447,727 L 1471,688 L 1492,644 L 1507,601 L 1516,561 L 1521,519 L 1520,462 L 1513,422 L 1508,407 L 1502,395 L 1492,381 Z M 1289,362 L 1286,360 L 1293,369 L 1302,386 L 1309,413 L 1309,458 L 1305,496 L 1296,538 L 1286,569 L 1269,606 L 1247,641 L 1218,676 L 1195,698 L 1159,726 L 1131,742 L 1103,752 L 1063,759 L 1044,759 L 1029,757 L 1002,748 L 1007,750 L 1014,756 L 1029,763 L 1058,770 L 1092,769 L 1114,765 L 1135,759 L 1166,744 L 1207,714 L 1241,681 L 1265,651 L 1284,620 L 1303,578 L 1316,533 L 1324,476 L 1325,437 L 1320,408 L 1307,382 Z M 896,320 L 883,320 L 875,324 L 871,328 L 866,341 L 866,357 L 869,367 L 874,375 L 885,384 L 886,383 L 883,378 L 881,368 L 881,358 L 884,347 L 890,338 L 900,332 L 910,332 L 902,323 Z M 953,302 L 952,303 L 958,320 L 958,340 L 953,364 L 940,394 L 941,398 L 945,401 L 959,400 L 969,375 L 973,355 L 973,335 L 970,323 L 959,306 L 957,306 Z M 939,267 L 940,273 L 942,276 L 946,278 L 955,278 L 971,266 L 977,266 L 982,269 L 973,262 L 956,253 L 951,254 L 947,260 Z M 1053,228 L 1072,251 L 1086,277 L 1092,295 L 1095,310 L 1095,333 L 1089,357 L 1073,385 L 1051,410 L 1034,425 L 1020,434 L 1042,428 L 1050,428 L 1056,430 L 1061,428 L 1079,410 L 1096,387 L 1105,368 L 1109,354 L 1110,323 L 1102,299 L 1100,288 L 1080,256 L 1076,253 L 1076,251 Z M 1152,174 L 1142,186 L 1141,191 L 1153,227 L 1166,255 L 1176,271 L 1189,287 L 1205,301 L 1199,296 L 1199,294 L 1189,282 L 1189,280 L 1182,271 L 1171,248 L 1157,209 L 1155,196 L 1155,176 L 1154,174 Z M 363,117 L 359,124 L 354,145 L 353,176 L 347,215 L 335,255 L 325,279 L 311,307 L 285,349 L 263,379 L 216,436 L 185,483 L 164,525 L 155,548 L 145,581 L 138,615 L 135,648 L 136,672 L 140,695 L 146,715 L 159,743 L 171,760 L 186,773 L 179,766 L 165,739 L 157,716 L 152,693 L 151,647 L 157,608 L 162,588 L 177,544 L 193,510 L 209,482 L 237,442 L 274,398 L 300,363 L 327,319 L 345,282 L 361,234 L 368,191 L 368,140 L 365,120 Z M 930,105 L 929,108 L 940,125 L 951,138 L 968,154 L 960,146 L 958,141 L 949,131 L 934,104 Z M 1363,78 L 1363,86 L 1358,98 L 1343,115 L 1332,137 L 1329,151 L 1329,168 L 1332,184 L 1337,199 L 1348,222 L 1368,254 L 1391,283 L 1423,316 L 1401,292 L 1401,290 L 1391,279 L 1370,249 L 1353,215 L 1347,197 L 1344,176 L 1347,152 L 1355,134 L 1375,108 L 1378,98 L 1378,92 L 1375,85 L 1370,80 Z" fill="#111111" fill-rule="evenodd"/>
|
||||
<path d="M 240,467 L 225,482 L 198,514 L 195,520 L 199,527 L 203,529 L 237,559 L 245,563 L 252,557 L 290,510 L 290,507 L 287,502 L 283,500 L 275,492 L 272,491 L 270,488 L 267,487 L 247,470 Z M 1300,384 L 1293,371 L 1279,352 L 1258,336 L 1228,319 L 1205,303 L 1186,285 L 1177,274 L 1157,239 L 1143,203 L 1139,183 L 1139,160 L 1141,151 L 1139,149 L 1114,185 L 1105,203 L 1098,231 L 1098,272 L 1103,298 L 1111,322 L 1127,351 L 1152,384 L 1160,402 L 1165,418 L 1168,449 L 1164,478 L 1162,481 L 1162,486 L 1158,500 L 1144,531 L 1151,528 L 1174,511 L 1189,495 L 1200,479 L 1227,423 L 1237,415 L 1247,418 L 1251,422 L 1254,430 L 1254,436 L 1256,441 L 1256,475 L 1250,499 L 1237,527 L 1225,546 L 1216,557 L 1216,559 L 1212,562 L 1172,610 L 1147,635 L 1121,656 L 1106,665 L 1090,672 L 1065,676 L 1052,675 L 1037,671 L 1013,657 L 1004,648 L 996,637 L 989,623 L 985,610 L 983,596 L 983,575 L 986,555 L 994,531 L 1009,506 L 1026,487 L 1055,462 L 1061,452 L 1063,440 L 1059,432 L 1044,429 L 1026,433 L 1025,430 L 1041,418 L 1063,396 L 1081,371 L 1090,351 L 1093,338 L 1093,304 L 1084,275 L 1074,256 L 1061,238 L 1032,208 L 976,163 L 948,136 L 929,111 L 927,105 L 920,95 L 915,81 L 913,81 L 896,126 L 892,141 L 890,161 L 894,183 L 900,193 L 910,202 L 915,209 L 919,219 L 920,260 L 922,264 L 926,266 L 937,267 L 942,264 L 952,252 L 957,252 L 986,270 L 1011,293 L 1022,308 L 1031,326 L 1036,343 L 1036,352 L 1034,358 L 1024,371 L 1005,386 L 985,396 L 971,400 L 944,402 L 940,399 L 939,394 L 952,364 L 957,339 L 956,316 L 949,298 L 939,288 L 920,280 L 897,280 L 871,288 L 852,300 L 838,316 L 832,328 L 826,356 L 826,382 L 831,399 L 840,414 L 855,429 L 855,433 L 814,465 L 794,478 L 768,492 L 745,502 L 715,512 L 688,518 L 659,522 L 604,522 L 595,520 L 585,520 L 561,516 L 528,508 L 496,498 L 494,496 L 485,494 L 478,490 L 460,484 L 417,464 L 373,440 L 368,440 L 366,445 L 364,464 L 364,479 L 357,550 L 358,558 L 362,563 L 401,580 L 422,591 L 431,597 L 454,619 L 469,641 L 480,666 L 480,670 L 482,673 L 482,692 L 480,698 L 473,709 L 464,719 L 422,759 L 395,778 L 373,788 L 341,796 L 306,799 L 265,798 L 232,794 L 219,791 L 201,784 L 179,769 L 165,754 L 152,732 L 141,703 L 135,673 L 134,643 L 137,614 L 143,584 L 156,542 L 165,520 L 181,488 L 198,460 L 217,433 L 268,371 L 295,332 L 312,303 L 333,257 L 344,223 L 349,199 L 352,174 L 353,138 L 347,91 L 345,88 L 343,91 L 336,129 L 317,191 L 292,253 L 278,279 L 255,311 L 186,385 L 145,436 L 113,484 L 86,536 L 76,561 L 68,587 L 60,632 L 60,694 L 64,719 L 69,738 L 76,758 L 88,783 L 110,814 L 124,829 L 144,846 L 176,863 L 213,875 L 247,880 L 296,879 L 327,874 L 354,867 L 383,857 L 410,845 L 450,822 L 473,805 L 496,783 L 516,755 L 526,734 L 531,719 L 537,685 L 537,656 L 535,640 L 528,611 L 519,585 L 519,572 L 523,566 L 529,565 L 545,571 L 586,579 L 632,583 L 675,581 L 710,575 L 758,559 L 791,542 L 827,516 L 847,498 L 878,463 L 891,451 L 901,450 L 918,457 L 955,457 L 983,451 L 984,454 L 960,472 L 940,493 L 902,538 L 858,600 L 816,665 L 764,741 L 735,781 L 704,819 L 675,848 L 649,869 L 634,879 L 601,896 L 547,916 L 525,922 L 520,922 L 496,928 L 489,928 L 484,930 L 432,935 L 374,935 L 336,932 L 286,924 L 240,912 L 220,905 L 180,886 L 161,873 L 151,864 L 149,864 L 133,849 L 128,847 L 130,856 L 146,883 L 173,911 L 175,911 L 192,927 L 194,927 L 202,934 L 225,948 L 258,965 L 309,984 L 350,994 L 409,1001 L 451,1001 L 476,999 L 518,992 L 549,984 L 602,965 L 626,954 L 664,933 L 687,918 L 716,896 L 743,872 L 761,853 L 782,828 L 801,802 L 828,759 L 863,693 L 923,564 L 931,551 L 939,545 L 947,547 L 951,553 L 950,574 L 938,608 L 936,618 L 936,645 L 941,670 L 947,687 L 960,710 L 967,719 L 988,739 L 1009,750 L 1025,755 L 1046,758 L 1071,757 L 1106,750 L 1126,743 L 1148,732 L 1174,714 L 1214,679 L 1243,645 L 1264,613 L 1284,571 L 1299,522 L 1307,470 L 1308,414 L 1305,398 Z M 888,318 L 899,320 L 908,327 L 914,337 L 918,349 L 918,364 L 914,376 L 906,384 L 896,388 L 881,383 L 872,374 L 867,365 L 864,351 L 866,336 L 870,328 L 879,320 Z M 1349,62 L 1336,62 L 1328,65 L 1321,70 L 1306,87 L 1296,108 L 1288,138 L 1282,176 L 1281,224 L 1284,254 L 1293,296 L 1302,324 L 1318,362 L 1340,403 L 1344,413 L 1350,437 L 1352,458 L 1350,493 L 1346,517 L 1336,543 L 1335,549 L 1362,515 L 1371,497 L 1377,472 L 1380,432 L 1384,417 L 1394,405 L 1403,404 L 1413,412 L 1424,431 L 1434,464 L 1434,469 L 1438,483 L 1441,509 L 1442,536 L 1440,563 L 1434,594 L 1422,629 L 1407,660 L 1376,708 L 1336,756 L 1309,784 L 1260,829 L 1232,857 L 1196,897 L 1176,922 L 1154,952 L 1121,1004 L 1112,1024 L 1110,1037 L 1111,1042 L 1143,1010 L 1162,988 L 1230,920 L 1337,818 L 1385,770 L 1410,741 L 1445,691 L 1467,650 L 1483,611 L 1495,570 L 1503,524 L 1505,499 L 1505,465 L 1500,422 L 1491,391 L 1483,376 L 1474,364 L 1453,343 L 1409,304 L 1375,265 L 1349,226 L 1333,191 L 1328,169 L 1328,150 L 1330,140 L 1337,123 L 1344,112 L 1357,98 L 1362,85 L 1362,75 L 1359,70 Z" fill="#F2CC00" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.6 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 166 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 50 KiB |
@@ -115,6 +115,9 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer text-center pt-0 px-lg-2 px-1">
|
||||
<p class="mb-3 text-sm">
|
||||
<a href="{{ route('dasar.privasi') }}" class="text-info font-weight-bold">Dasar Privasi</a>
|
||||
</p>
|
||||
<p class="mb-4 text-sm mx-auto">
|
||||
Masalah untuk log masuk?
|
||||
<a class="text-info text-gradient font-weight-bold">Hubungi
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
@props([
|
||||
'note' => '',
|
||||
'page' => null,
|
||||
'total' => null,
|
||||
])
|
||||
|
||||
<style>
|
||||
.bsas-ecert-footer {
|
||||
flex: 0 0 auto;
|
||||
margin-top: auto;
|
||||
padding-top: 12px;
|
||||
border-top: 2px solid var(--accent, #0f4c5c);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color: var(--muted, #5a6570);
|
||||
}
|
||||
.bsas-ecert-footer .footer-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
.bsas-ecert-footer .footer-note {
|
||||
margin: 0;
|
||||
font-size: 10px;
|
||||
text-align: left;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.bsas-ecert-footer .page-no {
|
||||
flex: 0 0 auto;
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<footer {{ $attributes->merge(['class' => 'bsas-ecert-footer']) }}>
|
||||
<div class="footer-row">
|
||||
<p class="footer-note">
|
||||
@if(trim($slot) !== '')
|
||||
{{ $slot }}
|
||||
@else
|
||||
{{ $note }}
|
||||
@endif
|
||||
</p>
|
||||
@if($page !== null && $total !== null)
|
||||
<div class="page-no">Page {{ $page }} of {{ $total }}</div>
|
||||
@elseif($page !== null)
|
||||
<div class="page-no">{{ $page }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,63 @@
|
||||
@props([
|
||||
'company' => 'Koperasi Permodalan Kelantan Berhad',
|
||||
'leftLogo' => null,
|
||||
'rightLogo' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$leftLogo = $leftLogo ?? asset('img/svg/logo-kopkb.svg');
|
||||
$rightLogo = $rightLogo ?? asset('img/svg/logo-arrahn-new.svg');
|
||||
@endphp
|
||||
|
||||
<style>
|
||||
.bsas-ecert-header {
|
||||
flex: 0 0 auto;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.bsas-ecert-header .brand-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
.bsas-ecert-header .logos {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.bsas-ecert-header .logos img {
|
||||
height: 78px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
.bsas-ecert-header .logos.is-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.bsas-ecert-header .company-heading {
|
||||
text-align: center;
|
||||
margin: 14px 0 0;
|
||||
}
|
||||
.bsas-ecert-header .company-heading .name {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .06em;
|
||||
color: var(--accent, #0f4c5c);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
|
||||
<header {{ $attributes->merge(['class' => 'bsas-ecert-header']) }}>
|
||||
<div class="brand-row">
|
||||
<div class="logos">
|
||||
<img src="{{ $leftLogo }}" alt="KPKB">
|
||||
</div>
|
||||
<div class="logos is-end">
|
||||
<img src="{{ $rightLogo }}" alt="Ar-Rahn">
|
||||
</div>
|
||||
</div>
|
||||
<div class="company-heading">
|
||||
<p class="name">{{ $company }}</p>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,35 @@
|
||||
@props([
|
||||
'leftLogo' => null,
|
||||
'rightLogo' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$leftLogo = $leftLogo ?? asset('img/svg/logo-kopkb.svg');
|
||||
$rightLogo = $rightLogo ?? asset('img/logo-arrahn.jpeg');
|
||||
@endphp
|
||||
|
||||
<style>
|
||||
.bsas-ecert-watermark {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 28px;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
opacity: .09;
|
||||
}
|
||||
.bsas-ecert-watermark img {
|
||||
height: 230px;
|
||||
width: auto;
|
||||
max-width: 300px;
|
||||
object-fit: contain;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div {{ $attributes->merge(['class' => 'bsas-ecert-watermark']) }} aria-hidden="true">
|
||||
<img src="{{ $leftLogo }}" alt="">
|
||||
<img src="{{ $rightLogo }}" alt="">
|
||||
</div>
|
||||
@@ -716,8 +716,6 @@
|
||||
var api_url = "{{ api_url_for_browser() }}";
|
||||
var kodcaw = "{{ $cawangan_info['kodcaw'] }}";
|
||||
var tagarrahnbid = "{{ $cawangan_info['tagarrahnbid'] }}";
|
||||
var min_komoditi = "{{ $min_komoditi }}";
|
||||
console.log('test api_arrahnbid: ', api_arrahnbid);
|
||||
$('#daftar_gadai').on('click', async function(event) {
|
||||
event.preventDefault();
|
||||
if ($(this).prop('disabled')) {
|
||||
@@ -756,42 +754,14 @@
|
||||
event.preventDefault();
|
||||
return false;
|
||||
} else {
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
url: api_url + '/api/komuditi/check',
|
||||
success: function(data) {
|
||||
var check_komuditi = Object.keys(data).length;
|
||||
if (check_komuditi == 0) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unit Komoditi Berbaki Minima',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komoditi'
|
||||
});
|
||||
$("#daftar_gadai").prop('disabled', false);
|
||||
event.preventDefault();
|
||||
return false;
|
||||
} else {
|
||||
if (Number(data['unit_komuditi']) <= min_komoditi) {
|
||||
$("#daftar_gadai").prop('disabled', false);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unit Komoditi Berbaki Minima',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komoditi'
|
||||
});
|
||||
event.preventDefault();
|
||||
return false;
|
||||
} else {
|
||||
if (icbaru.length > 0) {
|
||||
window.location.href =
|
||||
"{{ route('gadaian', ['noic' => $customer_info['kpbaru']]) }}";
|
||||
} else {
|
||||
window.location.href =
|
||||
"{{ route('gadaian', ['noic' => $customer_info['kplama']]) }}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Commodity is purchased via BSAS on Terima; no bulk stock gate.
|
||||
if (icbaru.length > 0) {
|
||||
window.location.href =
|
||||
"{{ route('gadaian', ['noic' => $customer_info['kpbaru']]) }}";
|
||||
} else {
|
||||
window.location.href =
|
||||
"{{ route('gadaian', ['noic' => $customer_info['kplama']]) }}";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -801,9 +771,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
var pembiayaanOnlineEnabled = @json(!empty(($cawangan_info['features'] ?? [])['pembiayaan_online']));
|
||||
|
||||
var tablegadai = initErahnDatatable('#myTable', {
|
||||
order: [[1, 'desc']],
|
||||
columnDefs: [
|
||||
{ targets: 2, visible: pembiayaanOnlineEnabled, className: pembiayaanOnlineEnabled ? '' : 'no-export' },
|
||||
{ targets: 0, orderable: false, width: '40px' },
|
||||
{ targets: -1, orderable: false, searchable: false, width: '70px' }
|
||||
]
|
||||
@@ -811,6 +784,7 @@
|
||||
|
||||
var xtawarruq = initErahnDatatable('#xtawarruq', {
|
||||
columnDefs: [
|
||||
{ targets: 2, visible: pembiayaanOnlineEnabled, className: pembiayaanOnlineEnabled ? '' : 'no-export' },
|
||||
{ targets: 0, orderable: false, width: '40px' }
|
||||
]
|
||||
});
|
||||
@@ -2067,7 +2041,8 @@
|
||||
harini.setHours(0, 0, 0, 0);
|
||||
|
||||
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
||||
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(2)').text();
|
||||
let selectedRow = $('input[name="belum"]:checked').closest('tr');
|
||||
let test1 = selectedRow.length ? selectedRow.closest('table').DataTable().row(selectedRow).data()[3] : '';
|
||||
let tarikhgadai2 = new Date(test1);
|
||||
tarikhgadai2.setHours(0, 0, 0, 0);
|
||||
if (+harini !== +tarikhgadai2) {
|
||||
@@ -2484,7 +2459,8 @@
|
||||
}
|
||||
|
||||
if ($("input[name='options']:checked").val() == 'belum_tebus') {
|
||||
let test1 = $('input[name="belum"]:checked').closest('tr').children('td:eq(2)').text();
|
||||
let selectedRow = $('input[name="belum"]:checked').closest('tr');
|
||||
let test1 = selectedRow.length ? selectedRow.closest('table').DataTable().row(selectedRow).data()[3] : '';
|
||||
let tarikhgadai2 = new Date(test1);
|
||||
tarikhgadai2.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ms">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Dasar Privasi | Kaunter arOS</title>
|
||||
<link rel="icon" href="{{ asset('img/icon_pkb.png') }}">
|
||||
<link href="{{ asset('css/login-v2.css') }}" rel="stylesheet">
|
||||
<style>
|
||||
body { background: #f4f7fb; color: #344767; }
|
||||
.privacy-container { max-width: 900px; margin: 0 auto; padding: 32px 20px; }
|
||||
.privacy-brand { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; }
|
||||
.privacy-brand img { width: 60px; height: auto; }
|
||||
.privacy-card { background: #fff; border-radius: 16px; padding: 40px; box-shadow: 0 8px 32px rgba(24, 49, 83, .08); }
|
||||
.privacy-card h1 { font-size: 2rem; }
|
||||
.privacy-card h2 { font-size: 1.2rem; margin-top: 28px; }
|
||||
.privacy-card p, .privacy-card li { line-height: 1.8; }
|
||||
.privacy-card ul { padding-left: 24px; }
|
||||
.privacy-back { display: inline-block; margin-top: 24px; color: #075985; text-decoration: underline; }
|
||||
a:focus-visible { outline: 3px solid #075985; outline-offset: 4px; }
|
||||
@media (max-width: 576px) {
|
||||
.privacy-container { padding: 20px 16px; }
|
||||
.privacy-card { padding: 24px 20px; }
|
||||
.privacy-card h1 { font-size: 1.7rem; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="privacy-container">
|
||||
<div class="privacy-brand">
|
||||
<img src="{{ asset('img/icon_pkb.png') }}" alt="Logo ar-Rahnu">
|
||||
<span class="font-weight-bold">Kaunter arOS · ar-rahn Online System</span>
|
||||
</div>
|
||||
<article class="privacy-card" aria-labelledby="privacy-title">
|
||||
<h1 id="privacy-title">Dasar Privasi</h1>
|
||||
<p class="text-sm text-muted">Versi dasar: 1.0 · Tarikh kemas kini: <time datetime="2026-09-27">27 September 2026</time></p>
|
||||
<h2>1. Pengenalan</h2>
|
||||
<p>Selamat datang ke sistem Kaunter arOS Koperasi Permodalan Kelantan Berhad (KoPKB). Kami amat menghargai kepercayaan yang anda berikan untuk mengendalikan maklumat peribadi anda. Dasar Privasi ini digubal untuk membantu anda memahami bagaimana kami mengumpul, menggunakan, mendedahkan dan melindungi data peribadi anda bagi urusan Ar-Rahn, dengan mengambil kira keperluan Akta Perlindungan Data Peribadi 2010 (PDPA) dan amalan keselamatan maklumat yang berkaitan.</p>
|
||||
<p>Dasar ini terpakai kepada kakitangan, pentadbir dan mana-mana pihak yang diberi kuasa untuk mengakses atau menggunakan sistem Kaunter arOS KoPKB, serta pengendalian data pelanggan dalam perkhidmatan yang diuruskan melalui sistem ini.</p>
|
||||
|
||||
<h2>2. Data yang Dikumpul</h2>
|
||||
<p>Kami mengumpul dan memproses maklumat yang berkaitan dengan urusan sistem, termasuk:</p>
|
||||
<ul>
|
||||
<li><strong>Maklumat Pengenalan Peribadi:</strong> Nama penuh, nombor pengenalan, alamat, alamat e-mel dan nombor telefon pelanggan atau pengguna.</li>
|
||||
<li><strong>Maklumat Akaun:</strong> Maklumat akaun pengguna, cawangan dan peranan akses dalam sistem.</li>
|
||||
<li><strong>Data Teknikal:</strong> Maklumat seperti alamat IP, jenis pelayar dan log aktiviti sistem yang direkodkan bagi tujuan operasi dan keselamatan.</li>
|
||||
<li><strong>Data Transaksi:</strong> Rekod pembiayaan, gadaian, maklumat marhun, pembayaran, penebusan, lelongan dan dokumen sokongan berkaitan.</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Tujuan Penggunaan Data</h2>
|
||||
<p>Data anda digunakan untuk tujuan berikut:</p>
|
||||
<ul>
|
||||
<li><strong>Operasi Sistem:</strong> Menguruskan akaun pengguna dan memproses urusan pelanggan serta transaksi Ar-Rahn.</li>
|
||||
<li><strong>Pengesahan:</strong> Mengesahkan identiti dan mengawal akses pengguna mengikut peranan serta cawangan yang dibenarkan.</li>
|
||||
<li><strong>Komunikasi:</strong> Menyampaikan notis berkaitan urusan, makluman pentadbiran dan sokongan pelanggan.</li>
|
||||
<li><strong>Pelaporan dan Penambahbaikan:</strong> Menyediakan laporan operasi, menyokong audit serta menambah baik prestasi dan kualiti sistem.</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Perkongsian & Pendedahan Data</h2>
|
||||
<p>Kami tidak menjual data peribadi anda. Akses, perkongsian atau pendedahan data dihadkan kepada keperluan urusan yang berkaitan, termasuk:</p>
|
||||
<ul>
|
||||
<li><strong>Kakitangan yang Diberi Kuasa:</strong> Kakitangan dan pentadbir KoPKB yang memerlukan maklumat untuk menjalankan tugas.</li>
|
||||
<li><strong>Pembekal Perkhidmatan:</strong> Penyedia teknologi atau perkhidmatan yang menyokong pengehosan, penyelenggaraan sistem dan pemprosesan pembayaran, jika berkaitan.</li>
|
||||
<li><strong>Pematuhan Undang-undang:</strong> Pihak berkuasa atau pihak lain apabila pendedahan diperlukan oleh undang-undang atau perintah mahkamah.</li>
|
||||
</ul>
|
||||
|
||||
<h2>5. Keselamatan Data</h2>
|
||||
<p>Langkah keselamatan teknikal dan pentadbiran digunakan untuk membantu melindungi data yang dikendalikan melalui sistem, termasuk kawalan akses mengikut peranan pengguna dan pengesahan akaun.</p>
|
||||
<p>Pengguna hendaklah mengakses sistem melalui sambungan HTTPS yang selamat, menjaga kerahsiaan kata laluan, tidak berkongsi akaun dan log keluar selepas selesai menggunakan sistem. Sebarang aktiviti yang mencurigakan hendaklah dilaporkan kepada pentadbir sistem.</p>
|
||||
|
||||
<h2>6. Hak Pengguna</h2>
|
||||
<p>Anda boleh menghubungi kami untuk mengemukakan permohonan berkaitan data peribadi anda, termasuk:</p>
|
||||
<ul>
|
||||
<li><strong>Akses & Pembetulan:</strong> Memohon semakan dan pembetulan maklumat peribadi yang tidak tepat atau tidak terkini.</li>
|
||||
<li><strong>Pemadaman:</strong> Memohon pemadaman akaun atau data dalam keadaan yang sesuai, tertakluk kepada keperluan penyimpanan rekod transaksi, audit dan undang-undang.</li>
|
||||
<li><strong>Sekatan:</strong> Memohon supaya pemprosesan data tertentu dihadkan, tertakluk kepada keperluan perkhidmatan dan kewajipan yang terpakai.</li>
|
||||
</ul>
|
||||
<p>Permohonan akan dinilai mengikut keperluan yang terpakai. Pengesahan identiti mungkin diperlukan sebelum permohonan diproses.</p>
|
||||
|
||||
<h2>7. Tempoh Penyimpanan</h2>
|
||||
<p>Data disimpan selama diperlukan untuk pengendalian urusan Ar-Rahn, penyelenggaraan rekod pembiayaan dan transaksi, audit serta pematuhan undang-undang. Selepas keperluan penyimpanan berakhir, data akan diuruskan untuk pemadaman atau penyahkenalpastian mengikut prosedur organisasi yang terpakai.</p>
|
||||
|
||||
<h2>8. Kuki & Teknologi Penjejakan</h2>
|
||||
<p>Sistem Kaunter arOS menggunakan kuki (cookies) dan sesi untuk menyokong log masuk, mengekalkan sesi pengguna dan melindungi permintaan dalam sistem. Anda boleh menguruskan pilihan kuki melalui tetapan pelayar. Menyekat kuki boleh menyebabkan fungsi tertentu, termasuk log masuk, tidak berfungsi dengan baik.</p>
|
||||
|
||||
<h2>9. Perubahan Dasar</h2>
|
||||
<p>Dasar ini boleh dikemas kini dari semasa ke semasa apabila terdapat perubahan pada perkhidmatan, pengendalian sistem atau keperluan organisasi. Versi terkini akan dipaparkan pada halaman ini. Sebarang perubahan besar akan dimaklumkan melalui e-mel atau notis dalam sistem sebelum tarikh kuat kuasa baharu.</p>
|
||||
|
||||
<h2>10. Hubungi Kami</h2>
|
||||
<p>Jika anda mempunyai pertanyaan, komen atau permohonan berkaitan dasar ini dan pengendalian data peribadi dalam sistem Kaunter arOS, sila hubungi:</p>
|
||||
<p><strong>AFRINA ALIMI</strong><br>
|
||||
Koperasi Permodalan Kelantan Berhad (KoPKB)<br>
|
||||
E-mel: <a href="mailto:afrina@koppkb.com">afrina@koppkb.com</a>
|
||||
</p>
|
||||
|
||||
<a class="privacy-back" href="{{ route('login') }}">Kembali ke Log Masuk</a>
|
||||
</article>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -817,32 +817,7 @@
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}else{
|
||||
$.ajax({
|
||||
method:'get',
|
||||
url: api_url + '/api/komuditi/check',
|
||||
success:function(data){
|
||||
var check_komuditi = Object.keys(data).length;
|
||||
if(check_komuditi == 0){
|
||||
$("#terima_gadai").prop('disabled', false);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unit Komuditi Berbaki Minumum',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komuditi'
|
||||
});
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}else{
|
||||
if(Number(data['unit_komuditi']) < pinjaman){
|
||||
$("#terima_gadai").prop('disabled', false);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Baki Unit Komuditi Tidak Mencukupi',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komuditi'
|
||||
});
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
// Commodity purchase is done via BSAS on Terima (server-side).
|
||||
if(pinjaman >= 10000 && pinjaman <= Number(pembiyaan_max_pelulus)){
|
||||
|
||||
//new added
|
||||
@@ -1179,10 +1154,6 @@
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1562,6 +1562,126 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
function bsasProgressHtml() {
|
||||
return '' +
|
||||
'<div class="text-left" id="bsas-progress-box">' +
|
||||
'<p class="mb-2">Sedang memproses pembelian komoditi...</p>' +
|
||||
'<ol class="mb-2 pl-3" style="list-style:none;padding-left:0;">' +
|
||||
'<li id="bsas-step-1" class="mb-2 small text-muted" data-state="pending">' +
|
||||
'<span class="bsas-step-icon mr-1">○</span>' +
|
||||
'<strong>1.</strong> Menghantar order ke BSAS' +
|
||||
'<div class="bsas-step-remark text-muted" style="margin-left:1.25rem;"></div>' +
|
||||
'</li>' +
|
||||
'<li id="bsas-step-2" class="mb-2 small text-muted" data-state="pending">' +
|
||||
'<span class="bsas-step-icon mr-1">○</span>' +
|
||||
'<strong>2.</strong> Menunggu keputusan (long poll)' +
|
||||
'<div class="bsas-step-remark text-muted" style="margin-left:1.25rem;"></div>' +
|
||||
'</li>' +
|
||||
'<li id="bsas-step-3" class="mb-2 small text-muted" data-state="pending">' +
|
||||
'<span class="bsas-step-icon mr-1">○</span>' +
|
||||
'<strong>3.</strong> Mengambil e-Cert bid, OTC dan STB & simpan gadai' +
|
||||
'<div class="bsas-step-remark text-muted" style="margin-left:1.25rem;"></div>' +
|
||||
'</li>' +
|
||||
'</ol>' +
|
||||
'<p class="mb-0 small text-muted">Sila tunggu, proses ini boleh mengambil masa 10–30 saat.</p>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
function setBsasStep(step, state, remark) {
|
||||
var $el = $('#bsas-step-' + step);
|
||||
if (!$el.length) {
|
||||
return;
|
||||
}
|
||||
var icon = '○';
|
||||
var color = 'text-muted';
|
||||
if (state === 'active') {
|
||||
icon = '●';
|
||||
color = 'text-primary font-weight-bold';
|
||||
} else if (state === 'done') {
|
||||
icon = '✓';
|
||||
color = 'text-success';
|
||||
} else if (state === 'error') {
|
||||
icon = '✕';
|
||||
color = 'text-danger';
|
||||
}
|
||||
$el.attr('data-state', state)
|
||||
.removeClass('text-muted text-primary text-success text-danger font-weight-bold')
|
||||
.addClass(color);
|
||||
$el.find('.bsas-step-icon').text(icon);
|
||||
$el.find('.bsas-step-remark').text(remark || '');
|
||||
}
|
||||
|
||||
function delayMs(ms) {
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
async function submitGadaiWithBsasProgress(func) {
|
||||
$("#terima_gadai").prop('disabled', true);
|
||||
|
||||
Swal.fire({
|
||||
title: 'Pembelian Komoditi BSAS',
|
||||
html: bsasProgressHtml(),
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false,
|
||||
showConfirmButton: false,
|
||||
didOpen: function () {
|
||||
Swal.showLoading();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
setBsasStep(1, 'active', 'Menyediakan & menghantar order...');
|
||||
await delayMs(1200);
|
||||
setBsasStep(1, 'done', 'Order dihantar.');
|
||||
|
||||
setBsasStep(2, 'active', 'Menunggu padanan BSAS...');
|
||||
await delayMs(800);
|
||||
|
||||
var response = await $.ajax({
|
||||
url: $(func).attr('action'),
|
||||
method: 'POST',
|
||||
data: $(func).serialize(),
|
||||
dataType: 'json',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
timeout: 90000
|
||||
});
|
||||
|
||||
setBsasStep(2, 'done', 'Keputusan diterima.');
|
||||
setBsasStep(3, 'active', 'Mengambil e-Cert bid, OTC dan STB & menyimpan gadai...');
|
||||
await delayMs(1000);
|
||||
setBsasStep(3, 'done', 'Selesai.');
|
||||
await delayMs(600);
|
||||
|
||||
window.location.href = (response && response.redirect)
|
||||
? response.redirect
|
||||
: "{{ route('customer_info') }}";
|
||||
} catch (err) {
|
||||
var msg = 'Gagal pembelian komoditi BSAS. Sila cuba lagi.';
|
||||
if (err && err.responseJSON && err.responseJSON.message) {
|
||||
msg = err.responseJSON.message;
|
||||
} else if (err && err.statusText === 'timeout') {
|
||||
msg = 'Proses BSAS tamat masa. Sila semak rekod BSAS / cuba semula.';
|
||||
}
|
||||
|
||||
var activeStep = $('#bsas-progress-box li[data-state="active"]').attr('id');
|
||||
var stepNum = activeStep ? parseInt(activeStep.replace('bsas-step-', ''), 10) : 2;
|
||||
setBsasStep(stepNum, 'error', msg);
|
||||
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Tidak Berjaya',
|
||||
text: msg
|
||||
}).then(function () {
|
||||
$("#terima_gadai").prop('disabled', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyGadai(func){
|
||||
$("#terima_gadai").prop('disabled', true);
|
||||
if (typeof event !== 'undefined' && event && event.preventDefault) {
|
||||
@@ -1653,32 +1773,7 @@
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}else{
|
||||
$.ajax({
|
||||
method:'get',
|
||||
url: api_url + '/api/komuditi/check',
|
||||
success:function(data){
|
||||
var check_komuditi = Object.keys(data).length;
|
||||
if(check_komuditi == 0){
|
||||
$("#terima_gadai").prop('disabled', false);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unit Komuditi Berbaki Minumum',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komuditi'
|
||||
});
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}else{
|
||||
if(Number(data['unit_komuditi']) < pinjaman){
|
||||
$("#terima_gadai").prop('disabled', false);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Baki Unit Komuditi Tidak Mencukupi',
|
||||
text: 'Sila Hubungi Operasi Untuk Membuat Pembelian Komuditi'
|
||||
});
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
// Commodity purchase is done via BSAS on Terima (server-side).
|
||||
if(pinjaman >= 10000 && pinjaman <= Number(pembiyaan_max_pelulus)){
|
||||
//new added
|
||||
$.ajax({
|
||||
@@ -1785,9 +1880,7 @@
|
||||
title: 'Telah Disahkan',
|
||||
text: `Komen : ${data.komen}`
|
||||
}).then(function(){
|
||||
|
||||
$(func).attr("onSubmit","return true;");
|
||||
$(func).submit();
|
||||
submitGadaiWithBsasProgress(func);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -1933,12 +2026,8 @@
|
||||
icon: 'success',
|
||||
title: 'Telah Disahkan'
|
||||
}).then(function(){
|
||||
|
||||
|
||||
$(func).attr("onSubmit","return true;");
|
||||
$(func).submit();
|
||||
submitGadaiWithBsasProgress(func);
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
else if(data.kelulusan == 'batal')
|
||||
@@ -1999,14 +2088,7 @@
|
||||
return false;
|
||||
} else {
|
||||
//insert code asal
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berjaya!',
|
||||
text: 'Pembiayaan Berjaya Disimpan'
|
||||
});
|
||||
|
||||
$(func).attr("onSubmit","return true;");
|
||||
$(func).submit();
|
||||
submitGadaiWithBsasProgress(func);
|
||||
return true;
|
||||
//end insert code asal
|
||||
}
|
||||
@@ -2018,10 +2100,6 @@
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb pb-3">
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">Home</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Komoditi BSAS</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="card-header text-center">{{ __('Rekod Komoditi BSAS') }}</div>
|
||||
<div class="card-body text-center">
|
||||
<div class="row justify-content-between mb-4">
|
||||
<div class="col text-left">
|
||||
<div class="form-group d-flex align-items-center">
|
||||
<label for="limit_view_bsas" style="width: 600px" class="mb-0">Had Paparan Rekod BSAS</label>
|
||||
<select onchange="loadBsasRecord()" name="limit_view_bsas" id="limit_view_bsas" class="form-control">
|
||||
<option selected value="20">20</option>
|
||||
<option value="100">100</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<button type="button" class="btn btn-primary" id="refresh_bsas" title="Muat Semula">
|
||||
<i class="fas fa-sync-alt" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="spinner-border" role="status" id="loading-spinner-bsas" style="display:none;">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<x-datatable
|
||||
id="rekod_bsas"
|
||||
filename="Rekod_Komoditi_BSAS"
|
||||
class="text-center"
|
||||
:columns="['Bil', 'Tarikh', 'UUID', 'No Rujukan', 'Cawangan', 'Pembeli', 'Bid Value', 'Murabaha', 'eCert No', 'Status', 'Oleh', 'Tindakan']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const formatter = new Intl.NumberFormat('en-US', {
|
||||
minimumFractionDigits: 2
|
||||
});
|
||||
|
||||
let api = "{{ api_url_for_browser() }}";
|
||||
let kodcaw = "{{ Auth::user()->cawangan }}";
|
||||
|
||||
var tablebsas = initErahnDatatable('#rekod_bsas', {
|
||||
pageLength: 1000,
|
||||
bLengthChange: false,
|
||||
deferRender: true,
|
||||
order: [[1, 'desc']],
|
||||
});
|
||||
|
||||
$('#refresh_bsas').on('click', function () {
|
||||
loadBsasRecord();
|
||||
});
|
||||
|
||||
$(function () {
|
||||
loadBsasRecord();
|
||||
});
|
||||
|
||||
function bsasStatusBadge(status) {
|
||||
var label = status || '-';
|
||||
var cls = 'secondary';
|
||||
if (status === 'confirmed') cls = 'success';
|
||||
else if (status === 'failed') cls = 'danger';
|
||||
else if (status === 'submitted' || status === 'pending') cls = 'warning';
|
||||
return '<span class="badge badge-' + cls + '">' + label + '</span>';
|
||||
}
|
||||
|
||||
function formatBsasDateTime(value) {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
var date = new Date(value);
|
||||
if (isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
var pad = function (n) { return String(n).padStart(2, '0'); };
|
||||
return date.getFullYear() + '-' +
|
||||
pad(date.getMonth() + 1) + '-' +
|
||||
pad(date.getDate()) + ' ' +
|
||||
pad(date.getHours()) + ':' +
|
||||
pad(date.getMinutes()) + ':' +
|
||||
pad(date.getSeconds());
|
||||
}
|
||||
|
||||
function bsasEcertAction(row) {
|
||||
var ecertNo = row['e_cert_no'] || '';
|
||||
var hasEcert = !!(row['has_bid_ecert'] || row['has_otc_ecert'] || row['has_stb_ecert']);
|
||||
var uuid = row['uuid'] || '';
|
||||
|
||||
if (!hasEcert || !uuid) {
|
||||
return '<span class="text-muted">-</span>';
|
||||
}
|
||||
|
||||
var url = "{{ url('/khazanah/komoditi/bsas/ecert') }}/" + encodeURIComponent(uuid);
|
||||
return '<a class="btn btn-sm btn-outline-primary" href="' + url + '" target="_blank" title="Lihat eCert ' + ecertNo + '">' +
|
||||
'<i class="fa fa-print" aria-hidden="true"></i> eCert' +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
function loadBsasRecord() {
|
||||
var selectedLimitView = $('#limit_view_bsas').find(':selected').val();
|
||||
|
||||
$('#loading-spinner-bsas').show();
|
||||
tablebsas.clear().draw();
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
url: api + '/api/komuditi/bsas/orders',
|
||||
data: {
|
||||
'limit_view': selectedLimitView,
|
||||
'kodcaw': kodcaw,
|
||||
},
|
||||
success: function (rekod) {
|
||||
var bilcount = 0;
|
||||
$.each(rekod, function (index, row) {
|
||||
bilcount++;
|
||||
var ecertNo = row['e_cert_no'] || '-';
|
||||
if ((row['has_bid_ecert'] || row['has_otc_ecert'] || row['has_stb_ecert']) && row['uuid']) {
|
||||
ecertNo = '<a href="{{ url('/khazanah/komoditi/bsas/ecert') }}/' + encodeURIComponent(row['uuid']) + '" target="_blank">' +
|
||||
(row['e_cert_no'] || 'eCert') +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
tablebsas.row.add([
|
||||
bilcount,
|
||||
formatBsasDateTime(row['created_at']),
|
||||
row['uuid'] || '-',
|
||||
row['norujukan'] || '-',
|
||||
row['kodcaw'] || '-',
|
||||
row['otc_counter_party'] || '-',
|
||||
formatter.format(Number(row['bid_value'] || 0)),
|
||||
formatter.format(Number(row['otc_murabaha_value'] || 0)),
|
||||
ecertNo,
|
||||
bsasStatusBadge(row['status']),
|
||||
row['created_by'] || '-',
|
||||
bsasEcertAction(row),
|
||||
]).draw(false);
|
||||
});
|
||||
tablebsas.draw();
|
||||
$('#loading-spinner-bsas').hide();
|
||||
},
|
||||
error: function () {
|
||||
$('#loading-spinner-bsas').hide();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Amaran!',
|
||||
text: 'Gagal memuatkan rekod BSAS'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
@@ -282,6 +282,10 @@
|
||||
<a href="{{ route('khazanah.indexwakil') }}"
|
||||
class="btn btn-info btn-lg btn-block mb-3">Surat Wakil</a>
|
||||
</div>
|
||||
<div class="col-4 px-2">
|
||||
<a href="{{ route('khazanah.bsas') }}"
|
||||
class="btn btn-info btn-lg btn-block mb-3">Komoditi BSAS</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,18 @@
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
@if(!empty($customer_info['photo_base64']))
|
||||
<div class="form-group row col-md-12">
|
||||
<div class="col-md-12 d-flex justify-content-center pb-3">
|
||||
<img src="data:{{ $customer_info['photo_mime'] ?? 'image/jpeg' }};base64,{{ $customer_info['photo_base64'] }}"
|
||||
alt="Gambar MyKad"
|
||||
width="120"
|
||||
height="160"
|
||||
style="object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-group row col-md-12">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
@@ -154,7 +166,7 @@
|
||||
<nav class="mb-3">
|
||||
<div class="nav nav-tabs" id="nav-tab" role="tablist">
|
||||
@php
|
||||
$activate_tab = request()->session()->pull('activate_tab', 'SAG_lama');
|
||||
$activate_tab = request()->session()->pull('activate_tab', 'SAG_baru');
|
||||
|
||||
$activate_tab_SAG_baru = $activate_tab === 'SAG_baru' ? 'active' : '';
|
||||
$aria_selected_SAG_baru = $activate_tab === 'SAG_baru' ? 'true' : 'false';
|
||||
@@ -171,77 +183,36 @@
|
||||
</nav>
|
||||
<div class="tab-content" id="navtawarruqdannottawarruq">
|
||||
<div class="tab-pane fade {{ $activate_pane_SAG_baru }}" id="nav-tawarruq" role="tabpanel" aria-labelledby="nav-tawarruq-tab">
|
||||
<table class="table table-striped table-hover" id="myTable" style="width: 100%">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Bil</th>
|
||||
<th>No Rujukan</th>
|
||||
<th>Tarikh Pembiayaan</th>
|
||||
<th>Tarikh Matang</th>
|
||||
<th>Baki Harga Jualan</th>
|
||||
<th>Baki Pembiayaan</th>
|
||||
<th>Margin</th>
|
||||
<th>Tempoh</th>
|
||||
<th>Keuntungan</th>
|
||||
<th>Lelong</th>
|
||||
<th>Pembayaran Terakhir</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<x-datatable
|
||||
id="myTable"
|
||||
filename="SAG_Baru"
|
||||
:columns="['Bil', 'No Rujukan', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Pembayaran Terakhir', 'Tarikh Ansuran Terkini']"
|
||||
/>
|
||||
</div>
|
||||
<div class="tab-pane fade {{ $activate_pane_SAG_lama }}" id="nav-xtawarruq" role="tabpanel" aria-labelledby="nav-xtawarruq-tab">
|
||||
<table id="xtawarruq" class="table table-striped table-hover" style="width:100%">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Bil</th>
|
||||
<th>No Rujukan</th>
|
||||
<th>Tarikh Pembiayaan</th>
|
||||
<th>Tarikh Matang</th>
|
||||
<th>Baki Harga Jualan</th>
|
||||
<th>Baki Pembiayaan</th>
|
||||
<th>Margin</th>
|
||||
<th>Tempoh</th>
|
||||
<th>Keuntungan</th>
|
||||
<th>Lelong</th>
|
||||
<th>Pembayaran Terakhir</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<x-datatable
|
||||
id="xtawarruq"
|
||||
filename="SAG_Lama"
|
||||
:columns="['Bil', 'No Rujukan', 'Tarikh Pembiayaan', 'Tarikh Matang', 'Baki Harga Jualan', 'Baki Pembiayaan', 'Margin', 'Tempoh', 'Keuntungan', 'Lelong', 'Pembayaran Terakhir', 'Tarikh Ansuran Terkini']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Sudah Tebus --}}
|
||||
|
||||
<table id="dahtebusTable" class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Bil</th>
|
||||
<th>No Rujukan</th>
|
||||
<th>Tarikh Penyelesaian Pembiayaan</th>
|
||||
<th>Baki Pembiayaan</th>
|
||||
<th>Margin</th>
|
||||
<th>Tempoh</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<x-datatable
|
||||
id="dahtebusTable"
|
||||
filename="SAG_Sudah_Tebus"
|
||||
:columns="['Bil', 'No Rujukan', 'Tarikh Penyelesaian Pembiayaan', 'Baki Pembiayaan', 'Margin', 'Tempoh']"
|
||||
/>
|
||||
|
||||
{{-- Lelong --}}
|
||||
|
||||
<table id="lelongTable" class="table table-striped table-hover" style="width:100%">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Bil</th>
|
||||
<th>No Rujukan</th>
|
||||
<th>Tarikh Lelong</th>
|
||||
<th>Tarikh Tuntut</th>
|
||||
<th>Pembiayaan</th>
|
||||
<th>Harga Jual</th>
|
||||
<th>Jum Tuntut/Bayar</th>
|
||||
<th>Keuntungan</th>
|
||||
<th>Caj Lelong</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<x-datatable
|
||||
id="lelongTable"
|
||||
filename="SAG_Lelong"
|
||||
:columns="['Bil', 'No Rujukan', 'Tarikh Lelong', 'Tarikh Tuntut', 'Pembiayaan', 'Harga Jual', 'Jum Tuntut/Bayar', 'Keuntungan', 'Caj Lelong']"
|
||||
/>
|
||||
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary" onclick="histfunc()">Rekod Pembiayaan</button>
|
||||
@@ -502,21 +473,15 @@
|
||||
|
||||
|
||||
|
||||
var tablegadai = $('#myTable').DataTable({
|
||||
"scrollX": true,
|
||||
order: [[1,'desc']]
|
||||
var tablegadai = initErahnDatatable('#myTable', {
|
||||
order: [[1, 'desc']]
|
||||
});
|
||||
|
||||
var xtawarruq = $('#xtawarruq').DataTable({
|
||||
"scrollX": true,
|
||||
});
|
||||
var xtawarruq = initErahnDatatable('#xtawarruq');
|
||||
|
||||
var tabledahtebus = $('#dahtebusTable').DataTable({
|
||||
});
|
||||
var tabledahtebus = initErahnDatatable('#dahtebusTable');
|
||||
|
||||
var tablelelong = $('#lelongTable').DataTable({
|
||||
"scrollX": true
|
||||
});
|
||||
var tablelelong = initErahnDatatable('#lelongTable');
|
||||
|
||||
var historybayarandatatable = $('#tablehistorybayaran').DataTable({
|
||||
"ordering": false
|
||||
@@ -634,6 +599,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){
|
||||
|
||||
var counter = 1;
|
||||
@@ -693,8 +697,8 @@
|
||||
let table_norujukan = gadai_detail["norujukan"];
|
||||
// let radio_action = "onclick=checkCanChangeGadaianDetail(" + "'" + table_norujukan + "'" + ")";
|
||||
|
||||
if(gadai_detail["percentpinj"] != 0)
|
||||
xtawarruq.row.add([
|
||||
if(gadai_detail["percentpinj"] != 0) {
|
||||
var ansuranRow = xtawarruq.row.add([
|
||||
'<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>',
|
||||
(function() {
|
||||
@@ -724,8 +728,11 @@
|
||||
let color = bayaranInfo.blocked ? 'red' : 'green';
|
||||
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
||||
bayaranInfo.tarikh + '</div>';
|
||||
})()
|
||||
})(),
|
||||
'Memuatkan...'
|
||||
]).draw();
|
||||
muatTarikhAnsuranTerkini(ansuranRow, gadai_detail['norujukan']);
|
||||
}
|
||||
}else{
|
||||
var taglel = '';
|
||||
if(gadai_detail['taglel'] == 1){
|
||||
@@ -757,7 +764,7 @@
|
||||
|
||||
let table_norujukan = gadai_detail["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"/>',
|
||||
// '<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() {
|
||||
@@ -787,8 +794,10 @@
|
||||
let color = bayaranInfo.blocked ? 'red' : 'green';
|
||||
return '<div style="white-space: nowrap; color: ' + color + '; font-weight: bold;">' +
|
||||
bayaranInfo.tarikh + '</div>';
|
||||
})()
|
||||
})(),
|
||||
'Memuatkan...'
|
||||
]).draw();
|
||||
muatTarikhAnsuranTerkini(ansuranRow, gadai_detail['norujukan']);
|
||||
}
|
||||
}else if(jenistebus == "sudah_tebus"){
|
||||
|
||||
@@ -914,6 +923,9 @@
|
||||
success: function(data){
|
||||
$('#myTable').parents('div.dataTables_wrapper').first().show();
|
||||
gadaiTable(data,"belum_tebus");
|
||||
if (typeof adjustErahnDatatables === 'function') {
|
||||
adjustErahnDatatables();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1447,6 +1459,9 @@
|
||||
url: api_url + "/api/customers/"+noic+"/gadai/belum_tebus/"+kodcaw,
|
||||
success: function(data){
|
||||
gadaiTable(data,"belum_tebus");
|
||||
if (typeof adjustErahnDatatables === 'function') {
|
||||
adjustErahnDatatables();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1695,9 +1710,10 @@
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e){
|
||||
$($.fn.dataTable.tables(true)).DataTable()
|
||||
.columns.adjust();
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function(){
|
||||
if (typeof adjustErahnDatatables === 'function') {
|
||||
adjustErahnDatatables();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -73,43 +73,81 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Rekod Pembelian/Penjualan Komoditi') }}</div>
|
||||
<div class="card-header">{{ __('Rekod Komoditi') }}</div>
|
||||
<div class="card-body text-center">
|
||||
<div class="row justify-content-between mb-4">
|
||||
<div class="col text-left">
|
||||
<div class="form-group d-flex align-items-center">
|
||||
<label for="limit-komoditi" style="width: 600px" class="mb-0">Had Paparan Rekod Komoditi</label>
|
||||
<select onchange="loadKomoditiRecord()" name="limit_view" id="limit_view" class="form-control">
|
||||
<option selected value="20">20</option>
|
||||
<option value="100">100</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
<option disabled>Untuk rekod keseluruhan, sila print</option>
|
||||
</select>
|
||||
</div>
|
||||
<ul class="nav nav-tabs mb-3" id="komoditi-rekod-tab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="tab-manual-link" data-toggle="tab" href="#tab-manual" role="tab" aria-controls="tab-manual" aria-selected="true">Beli / Jual Manual</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="tab-bsas-link" data-toggle="tab" href="#tab-bsas" role="tab" aria-controls="tab-bsas" aria-selected="false">Pembelian BSAS</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="komoditi-rekod-tabContent">
|
||||
<div class="tab-pane fade show active" id="tab-manual" role="tabpanel" aria-labelledby="tab-manual-link">
|
||||
<div class="row justify-content-between mb-4">
|
||||
<div class="col text-left">
|
||||
<div class="form-group d-flex align-items-center">
|
||||
<label for="limit_view" style="width: 600px" class="mb-0">Had Paparan Rekod Komoditi</label>
|
||||
<select onchange="loadKomoditiRecord()" name="limit_view" id="limit_view" class="form-control">
|
||||
<option selected value="20">20</option>
|
||||
<option value="100">100</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
<option disabled>Untuk rekod keseluruhan, sila print</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<a href="{{ route('laporan.komoditi') }}" target="_blank" class="btn btn-primary" title="Cetak Rekod Jual/Beli Komoditi"><i class="fa fa-print" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="spinner-border" role="status" id="loading-spinner">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<x-datatable
|
||||
id="rekod_komuditi"
|
||||
filename="Rekod_Komoditi_Manual"
|
||||
class="text-center"
|
||||
:columns="['Bil', 'No Sijil', 'Tarikh', 'Masa', 'Nilai Komoditi', 'Transaksi Oleh', 'Transaksi']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<a href="{{ route('laporan.komoditi') }}" target="_blank" class="btn btn-primary" title="Cetak Rekod Jual/Beli Komoditi"><i class="fa fa-print" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="spinner-border" role="status" id="loading-spinner">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<table id="rekod_komuditi" class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Bil</th>
|
||||
<th>No Sijil</th>
|
||||
<th>Tarikh</th>
|
||||
<th>Masa</th>
|
||||
<th>Nilai Komoditi</th>
|
||||
<th>Transaksi Oleh</th>
|
||||
<th>Transaksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div class="tab-pane fade" id="tab-bsas" role="tabpanel" aria-labelledby="tab-bsas-link">
|
||||
<div class="row justify-content-between mb-4">
|
||||
<div class="col text-left">
|
||||
<div class="form-group d-flex align-items-center">
|
||||
<label for="limit_view_bsas" style="width: 600px" class="mb-0">Had Paparan Rekod BSAS</label>
|
||||
<select onchange="loadBsasRecord()" name="limit_view_bsas" id="limit_view_bsas" class="form-control">
|
||||
<option selected value="20">20</option>
|
||||
<option value="100">100</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<button type="button" class="btn btn-primary" id="refresh_bsas" title="Muat Semula">
|
||||
<i class="fas fa-sync-alt" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="spinner-border" role="status" id="loading-spinner-bsas" style="display:none;">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<x-datatable
|
||||
id="rekod_bsas"
|
||||
filename="Rekod_Komoditi_BSAS"
|
||||
class="text-center"
|
||||
:columns="['Bil', 'Tarikh', 'UUID', 'No Rujukan', 'Cawangan', 'Pembeli', 'Bid Value', 'Murabaha', 'eCert No', 'Status', 'Oleh', 'Tindakan']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,15 +277,44 @@
|
||||
<script>
|
||||
let api_url = "{{ api_url_for_browser() }}";
|
||||
|
||||
var tablerekod = $('#rekod_komuditi').DataTable( {
|
||||
"pageLength": 1000,
|
||||
"bLengthChange": false,
|
||||
var tablerekod = initErahnDatatable('#rekod_komuditi', {
|
||||
pageLength: 1000,
|
||||
bLengthChange: false,
|
||||
deferRender: true,
|
||||
order: [[2, 'desc']],
|
||||
});
|
||||
|
||||
var tablebsas = initErahnDatatable('#rekod_bsas', {
|
||||
pageLength: 1000,
|
||||
bLengthChange: false,
|
||||
deferRender: true,
|
||||
order: [[1, 'desc']],
|
||||
});
|
||||
|
||||
var bsasLoaded = false;
|
||||
|
||||
$(document).ready( function () {
|
||||
checkKomuditi();
|
||||
});
|
||||
|
||||
$('#komoditi-rekod-tab a[data-toggle="tab"]').on('shown.bs.tab', function () {
|
||||
if (typeof adjustErahnDatatables === 'function') {
|
||||
adjustErahnDatatables();
|
||||
}
|
||||
});
|
||||
|
||||
$('#tab-bsas-link').on('shown.bs.tab', function () {
|
||||
if (!bsasLoaded) {
|
||||
loadBsasRecord();
|
||||
} else if (typeof adjustErahnDatatables === 'function') {
|
||||
adjustErahnDatatables();
|
||||
}
|
||||
});
|
||||
|
||||
$('#refresh_bsas').on('click', function () {
|
||||
loadBsasRecord();
|
||||
});
|
||||
|
||||
const formatter = new Intl.NumberFormat('en-US', {
|
||||
minimumFractionDigits: 2
|
||||
});
|
||||
@@ -395,6 +462,101 @@
|
||||
})
|
||||
}
|
||||
|
||||
function bsasStatusBadge(status) {
|
||||
var label = status || '-';
|
||||
var cls = 'secondary';
|
||||
if (status === 'confirmed') cls = 'success';
|
||||
else if (status === 'failed') cls = 'danger';
|
||||
else if (status === 'submitted' || status === 'pending') cls = 'warning';
|
||||
return '<span class="badge badge-' + cls + '">' + label + '</span>';
|
||||
}
|
||||
|
||||
function formatBsasDateTime(value) {
|
||||
if (!value) {
|
||||
return '-';
|
||||
}
|
||||
var date = new Date(value);
|
||||
if (isNaN(date.getTime())) {
|
||||
return value;
|
||||
}
|
||||
var pad = function (n) { return String(n).padStart(2, '0'); };
|
||||
return date.getFullYear() + '-' +
|
||||
pad(date.getMonth() + 1) + '-' +
|
||||
pad(date.getDate()) + ' ' +
|
||||
pad(date.getHours()) + ':' +
|
||||
pad(date.getMinutes()) + ':' +
|
||||
pad(date.getSeconds());
|
||||
}
|
||||
|
||||
function bsasEcertAction(row) {
|
||||
var ecertNo = row['e_cert_no'] || '';
|
||||
var hasEcert = !!(row['has_bid_ecert'] || row['has_otc_ecert'] || row['has_stb_ecert']);
|
||||
var uuid = row['uuid'] || '';
|
||||
|
||||
if (!hasEcert || !uuid) {
|
||||
return '<span class="text-muted">-</span>';
|
||||
}
|
||||
|
||||
var url = "{{ url('/komoditi/bsas/ecert') }}/" + encodeURIComponent(uuid);
|
||||
return '<a class="btn btn-sm btn-outline-primary" href="' + url + '" target="_blank" title="Lihat eCert ' + ecertNo + '">' +
|
||||
'<i class="fa fa-print" aria-hidden="true"></i> eCert' +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
function loadBsasRecord()
|
||||
{
|
||||
var selectedLimitView = $('#limit_view_bsas').find(':selected').val();
|
||||
|
||||
$('#loading-spinner-bsas').show();
|
||||
tablebsas.clear().draw();
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
url: api_url + '/api/komuditi/bsas/orders',
|
||||
data: {
|
||||
'limit_view': selectedLimitView,
|
||||
},
|
||||
success: function (rekod) {
|
||||
var bilcount = 0;
|
||||
$.each(rekod, function (index, row) {
|
||||
bilcount++;
|
||||
var ecertNo = row['e_cert_no'] || '-';
|
||||
if ((row['has_bid_ecert'] || row['has_otc_ecert'] || row['has_stb_ecert']) && row['uuid']) {
|
||||
ecertNo = '<a href="{{ url('/komoditi/bsas/ecert') }}/' + encodeURIComponent(row['uuid']) + '" target="_blank">' +
|
||||
(row['e_cert_no'] || 'eCert') +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
tablebsas.row.add([
|
||||
bilcount,
|
||||
formatBsasDateTime(row['created_at']),
|
||||
row['uuid'] || '-',
|
||||
row['norujukan'] || '-',
|
||||
row['kodcaw'] || '-',
|
||||
row['otc_counter_party'] || '-',
|
||||
formatter.format(Number(row['bid_value'] || 0)),
|
||||
formatter.format(Number(row['otc_murabaha_value'] || 0)),
|
||||
ecertNo,
|
||||
bsasStatusBadge(row['status']),
|
||||
row['created_by'] || '-',
|
||||
bsasEcertAction(row),
|
||||
]).draw(false);
|
||||
});
|
||||
tablebsas.draw();
|
||||
bsasLoaded = true;
|
||||
$('#loading-spinner-bsas').hide();
|
||||
},
|
||||
error: function () {
|
||||
bsasLoaded = false;
|
||||
$('#loading-spinner-bsas').hide();
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Amaran!',
|
||||
text: 'Gagal memuatkan rekod BSAS'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#detail_komuditi').on('show.bs.modal', function(event) {
|
||||
var button = $(event.relatedTarget);
|
||||
var kodproduk = button.data('kodproduk');
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var api_url = '{{ api_url_for_browser() }}';
|
||||
var table_margin = $('#table-margin').DataTable();
|
||||
|
||||
$.ajax({
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
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']"
|
||||
:columns="['Bil', 'Status', 'SAG', 'Pelanggan', 'No KP', 'Bank', 'No Akaun', 'Pinjaman (RM)', 'Rujukan Bayaran', 'Dokumen', 'Tindakan']"
|
||||
:skipExport="['Dokumen', 'Tindakan']"
|
||||
>
|
||||
@foreach($lines as $line)
|
||||
@@ -94,7 +94,6 @@
|
||||
<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">
|
||||
@@ -113,6 +112,13 @@
|
||||
@else
|
||||
<span class="text-muted small">Tiada slip</span>
|
||||
@endif
|
||||
@if(!empty($line['borang_file_id']))
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{{ route('pembiayaan.online.operasi.borang', ['kodcaw' => $kodcaw, 'id' => $line['id']]) }}"
|
||||
target="_blank">
|
||||
Borang Pengesahan
|
||||
</a>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-nowrap">
|
||||
@if(in_array($st, ['IN_BATCH', 'OPS_REVIEW'], true))
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
@else
|
||||
<span class="text-muted small">Tiada slip</span>
|
||||
@endif
|
||||
@if(!empty($line['borang_file_id']))
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{{ route('pembiayaan.online.pc.borang', ['id' => $line['id']]) }}"
|
||||
target="_blank">
|
||||
Borang Pengesahan
|
||||
</a>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@@ -274,11 +274,11 @@
|
||||
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'] ?? '' }}">
|
||||
data-bukti-akaun="{{ $line['bukti_akaun_file_id'] ?? '' }}"
|
||||
data-borang-file="{{ $line['borang_file_id'] ?? '' }}">
|
||||
Semak
|
||||
</button>
|
||||
@endif
|
||||
@@ -286,11 +286,11 @@
|
||||
data-id="{{ $line['id'] }}"
|
||||
data-kodbank="{{ $line['kodbank'] ?? '' }}"
|
||||
data-noakaun="{{ $line['noakaun'] ?? '' }}"
|
||||
data-namaakaun="{{ $line['nama_akaun'] ?? '' }}"
|
||||
data-namabank="{{ $line['nama_bank'] ?? '' }}"
|
||||
data-nota="{{ $line['nota'] ?? '' }}"
|
||||
data-norujukan="{{ $line['norujukan'] ?? '' }}"
|
||||
data-bukti-akaun="{{ $line['bukti_akaun_file_id'] ?? '' }}">
|
||||
data-bukti-akaun="{{ $line['bukti_akaun_file_id'] ?? '' }}"
|
||||
data-borang-file="{{ $line['borang_file_id'] ?? '' }}">
|
||||
Edit
|
||||
</button>
|
||||
</td>
|
||||
@@ -390,10 +390,6 @@
|
||||
<label>No. Akaun</label>
|
||||
<input type="text" name="noakaun" id="editNoakaun" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Nama Akaun</label>
|
||||
<input type="text" name="nama_akaun" id="editNamaakaun" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Slip Bank / Bukti Akaun</label>
|
||||
<input type="file" name="bukti_akaun" id="editBuktiAkaun" class="form-control-file"
|
||||
@@ -405,6 +401,17 @@
|
||||
</div>
|
||||
<small class="text-muted">PDF / imej slip akaun bank pelanggan (maks 4MB)</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Borang Pengesahan Penerimaan Pembiayaan Secara Atas Talian (Online)</label>
|
||||
<input type="file" name="borang" id="editBorang" class="form-control-file"
|
||||
accept=".pdf,.jpg,.jpeg,.png,.gif">
|
||||
<div id="editBorangExisting" class="mt-2" style="display:none;">
|
||||
<a href="#" id="editBorangLink" class="btn btn-sm btn-outline-primary" target="_blank">
|
||||
Lihat borang sedia ada
|
||||
</a>
|
||||
</div>
|
||||
<small class="text-muted">PDF / imej borang yang ditandatangani pelanggan (maks 4MB). Kosongkan jika tidak mahu ganti fail sedia ada.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Nota</label>
|
||||
<textarea name="nota" id="editNota" class="form-control" rows="2"></textarea>
|
||||
@@ -462,10 +469,6 @@
|
||||
<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>
|
||||
@@ -485,9 +488,12 @@
|
||||
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;">
|
||||
<a href="#" id="verifyBuktiAkaunLink" class="btn btn-sm btn-outline-primary mb-2" target="_blank" style="display:none;">
|
||||
Lihat Bukti Akaun Bank
|
||||
</a>
|
||||
<a href="#" id="verifyBorangLink" class="btn btn-sm btn-outline-primary" target="_blank" style="display:none;">
|
||||
Lihat Borang Pengesahan
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="d-block">Pratonton SAG</label>
|
||||
@@ -576,7 +582,6 @@
|
||||
$('#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) {
|
||||
@@ -592,6 +597,11 @@
|
||||
} else {
|
||||
$('#verifyBuktiAkaunLink').hide();
|
||||
}
|
||||
if ($(this).data('borangFile')) {
|
||||
$('#verifyBorangLink').attr('href', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/borang").show();
|
||||
} else {
|
||||
$('#verifyBorangLink').hide();
|
||||
}
|
||||
$('#verifyModal').modal('show');
|
||||
});
|
||||
|
||||
@@ -605,10 +615,10 @@
|
||||
$('#editNorujukan').text($(this).data('norujukan'));
|
||||
$('#editKodbank').val($(this).data('kodbank'));
|
||||
$('#editNoakaun').val($(this).data('noakaun'));
|
||||
$('#editNamaakaun').val($(this).data('namaakaun'));
|
||||
$('#editNamabank').val($(this).data('namabank'));
|
||||
$('#editNota').val($(this).data('nota'));
|
||||
$('#editBuktiAkaun').val('');
|
||||
$('#editBorang').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");
|
||||
@@ -616,6 +626,12 @@
|
||||
} else {
|
||||
$('#editBuktiAkaunExisting').hide();
|
||||
}
|
||||
if ($(this).data('borangFile')) {
|
||||
$('#editBorangLink').attr('href', "{{ url('/pembiayaan-online/pc/lines') }}/" + id + "/borang");
|
||||
$('#editBorangExisting').show();
|
||||
} else {
|
||||
$('#editBorangExisting').hide();
|
||||
}
|
||||
$('#editModal').modal('show');
|
||||
});
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
<th style="width:13%">No. KP</th>
|
||||
<th style="width:11%">Bank</th>
|
||||
<th style="width:13%">No. Akaun</th>
|
||||
<th>Nama Akaun</th>
|
||||
<th>No. Telefon</th>
|
||||
<th style="width:12%">Pinjaman (RM)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -271,7 +271,7 @@
|
||||
<td class="num">{{ $line['nokp'] ?? '-' }}</td>
|
||||
<td>{{ $line['nama_bank'] ?? ($line['kodbank'] ?? '-') }}</td>
|
||||
<td class="num">{{ $line['noakaun'] ?? '-' }}</td>
|
||||
<td>{{ $line['nama_akaun'] ?? '-' }}</td>
|
||||
<td>{{ !empty($line['telefon']) ? $line['telefon'] : '-' }}</td>
|
||||
<td class="amt">{{ number_format((float) ($line['pinjaman'] ?? 0), 2) }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
@@ -306,7 +306,7 @@
|
||||
|
||||
<div class="signs">
|
||||
<div class="sign-box">
|
||||
<div class="role">Tandatangan Operasi</div>
|
||||
<div class="role">Disemak oleh</div>
|
||||
<div class="sign-line">
|
||||
<p>Nama: {{ $opsBy }}</p>
|
||||
<p>Jawatan: Operasi</p>
|
||||
@@ -314,10 +314,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="sign-box">
|
||||
<div class="role">Pengurus Besar</div>
|
||||
<div class="role">Disahkan oleh</div>
|
||||
<div class="sign-line">
|
||||
<p>Nama:</p>
|
||||
<p>Cop:</p>
|
||||
<p>Jawatan:</p>
|
||||
<p>Tarikh:</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>BSAS eCert — {{ $ecert_no ?? 'Preview' }}</title>
|
||||
<style>
|
||||
:root {
|
||||
--ink: #1a2332;
|
||||
--muted: #5a6570;
|
||||
--line: #c5a572;
|
||||
--line-soft: #e2d4bc;
|
||||
--accent: #0f4c5c;
|
||||
--paper: #fbf8f2;
|
||||
--panel: #ffffff;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #d9dde3;
|
||||
color: var(--ink);
|
||||
font-family: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
|
||||
}
|
||||
|
||||
.preview-bar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 16px;
|
||||
background: #0f4c5c;
|
||||
color: #fff;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
.preview-bar .badge {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border: 1px solid rgba(255,255,255,.55);
|
||||
border-radius: 3px;
|
||||
letter-spacing: .08em;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.preview-bar button,
|
||||
.preview-bar a {
|
||||
border: 0;
|
||||
background: #c5a572;
|
||||
color: #1a2332;
|
||||
font-weight: 700;
|
||||
padding: 7px 14px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sheet-stack {
|
||||
padding: 24px 12px 48px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.page {
|
||||
position: relative;
|
||||
width: 210mm;
|
||||
min-height: 297mm;
|
||||
background: var(--paper);
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,.18);
|
||||
overflow: hidden;
|
||||
padding: 16mm 16mm 18mm;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: calc(297mm - 34mm);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.cert-title {
|
||||
margin: 0 0 6px;
|
||||
text-align: center;
|
||||
font-size: 22px;
|
||||
letter-spacing: .18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
}
|
||||
.cert-no {
|
||||
text-align: center;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.cert-no strong {
|
||||
color: var(--accent);
|
||||
letter-spacing: .04em;
|
||||
}
|
||||
|
||||
.gold-rule {
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, var(--line), transparent);
|
||||
margin: 0 8%;
|
||||
}
|
||||
|
||||
.statement {
|
||||
margin: 20px auto 24px;
|
||||
max-width: 92%;
|
||||
text-align: center;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.65;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.section-label {
|
||||
margin: 0 0 10px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 11px;
|
||||
letter-spacing: .16em;
|
||||
text-transform: uppercase;
|
||||
color: var(--accent);
|
||||
font-weight: 700;
|
||||
border-left: 3px solid var(--line);
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.detail-panel {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line-soft);
|
||||
border-radius: 2px;
|
||||
padding: 14px 16px 8px;
|
||||
}
|
||||
|
||||
.detail-grid {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
.detail-grid tr td {
|
||||
padding: 7px 8px;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid #eee6d8;
|
||||
}
|
||||
.detail-grid tr:last-child td {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.detail-grid .label {
|
||||
width: 38%;
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
.detail-grid .value {
|
||||
color: var(--ink);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.commodity-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.commodity-table th,
|
||||
.commodity-table td {
|
||||
border: 1px solid var(--line-soft);
|
||||
padding: 10px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
.commodity-table th {
|
||||
background: #f3eee4;
|
||||
color: var(--accent);
|
||||
letter-spacing: .06em;
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
}
|
||||
.commodity-table td.num {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.murabaha-box {
|
||||
margin-top: 14px;
|
||||
padding: 10px 12px;
|
||||
border: 1px dashed var(--line);
|
||||
background: rgba(197, 165, 114, .08);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.murabaha-box .k {
|
||||
font-size: 11px;
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
}
|
||||
.murabaha-box .v {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
@media print {
|
||||
body { background: #fff; }
|
||||
.preview-bar { display: none !important; }
|
||||
.sheet-stack { padding: 0; gap: 0; }
|
||||
.page {
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
page-break-after: always;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
.page:last-child { page-break-after: auto; }
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@php
|
||||
$certificates = $certificates ?? [];
|
||||
$lines = $lines ?? [];
|
||||
$ecertNo = $ecert_no ?? 'CPO21OCT26-0000031-000';
|
||||
$isDummy = $isDummy ?? false;
|
||||
$pageTotal = count($certificates) + 1;
|
||||
@endphp
|
||||
|
||||
<div class="preview-bar">
|
||||
<div>
|
||||
@if($isDummy)
|
||||
<span class="badge">DUMMY PREVIEW</span>
|
||||
BSAS e-Certificate layout — {{ $pageTotal }} pages A4
|
||||
@else
|
||||
BSAS e-Certificate — {{ $ecertNo }}
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" onclick="window.print()">Print / PDF</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sheet-stack">
|
||||
@foreach($certificates as $index => $certificate)
|
||||
<section class="page">
|
||||
<x-print.bsas.watermark />
|
||||
|
||||
<div class="content">
|
||||
<x-print.bsas.header />
|
||||
|
||||
<div class="page-body">
|
||||
<h1 class="cert-title">{{ $certificate['title'] }}</h1>
|
||||
<div class="cert-no">Certificate Number: <strong>{{ $certificate['ecert_no'] ?? $ecertNo }}</strong></div>
|
||||
<div class="gold-rule"></div>
|
||||
|
||||
<p class="statement">{!! $certificate['statement'] !!}</p>
|
||||
|
||||
<h2 class="section-label">Detail</h2>
|
||||
<div class="detail-panel">
|
||||
<table class="detail-grid">
|
||||
@foreach($certificate['rows'] as $row)
|
||||
<tr>
|
||||
<td class="label">{{ $row['label'] }}</td>
|
||||
<td class="value">{{ $row['value'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
@if(!empty($certificate['show_murabaha']))
|
||||
<div class="murabaha-box">
|
||||
<span class="k">Murabaha Value</span>
|
||||
<span class="v">{{ $certificate['currency'] ?? 'MYR' }} {{ $certificate['murabaha'] }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-print.bsas.footer
|
||||
:page="$index + 1"
|
||||
:total="$pageTotal"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@endforeach
|
||||
|
||||
<section class="page">
|
||||
<x-print.bsas.watermark />
|
||||
|
||||
<div class="content">
|
||||
<x-print.bsas.header />
|
||||
|
||||
<div class="page-body">
|
||||
<h1 class="cert-title" style="font-size:18px;">Commodity Schedule</h1>
|
||||
<div class="cert-no">Certificate Number: <strong>{{ $ecertNo }}</strong></div>
|
||||
<div class="gold-rule"></div>
|
||||
|
||||
<h2 class="section-label" style="margin-top:28px;">Commodity Information</h2>
|
||||
<div class="detail-panel">
|
||||
<table class="commodity-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Commodity Supplying Participant</th>
|
||||
<th style="width:28%;text-align:right;">Commodity Volume</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($lines as $line)
|
||||
<tr>
|
||||
<td>{{ $line['supplier'] ?? '-' }}</td>
|
||||
<td class="num">{{ $line['volume'] ?? '-' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<x-print.bsas.footer :page="$pageTotal" :total="$pageTotal">
|
||||
This schedule forms part of Certificate No. {{ $ecertNo }}
|
||||
</x-print.bsas.footer>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -556,9 +556,30 @@
|
||||
</table>
|
||||
|
||||
@php
|
||||
$komuditi = Http::withOptions(['verify' => config('app.api_verify')])->get($api_url . '/api/komuditi/check')->json();
|
||||
$product = Http::withOptions(['verify' => config('app.api_verify')])->get($api_url . '/api/komuditi/description',['kodproduk'=>$komuditi['kodproduct']])->json();
|
||||
$kuantiti = $gadai_detail['pinjaman']/$komuditi['nilai'];
|
||||
$bsasSag = Http::withOptions(['verify' => config('app.api_verify')])->get($api_url . '/api/komuditi/bsas/order/norujukan/' . urlencode($gadai_detail['norujukan']));
|
||||
|
||||
$komuditi = [];
|
||||
$product = [];
|
||||
$kuantiti = 0;
|
||||
|
||||
if ($bsasSag->successful() && is_array($bsasSag->json())) {
|
||||
$bsasPayload = $bsasSag->json();
|
||||
$komuditi = $bsasPayload['komoditi'] ?? [];
|
||||
$product = $bsasPayload['product'] ?? [];
|
||||
$kuantiti = (float) ($bsasPayload['kuantiti'] ?? 0);
|
||||
}
|
||||
|
||||
if (!is_array($komuditi)) {
|
||||
$komuditi = [];
|
||||
}
|
||||
if (!is_array($product)) {
|
||||
$product = [
|
||||
'product_code' => $komuditi['kodproduct'] ?? '',
|
||||
'kodproduk' => $komuditi['kodproduct'] ?? '',
|
||||
'description' => '',
|
||||
'unit' => 'TAN',
|
||||
];
|
||||
}
|
||||
@endphp
|
||||
|
||||
<table style="margin-bottom:10px;" id="keuntungan">
|
||||
@@ -576,7 +597,7 @@
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Kod Produk / Diskripsi</td>
|
||||
<td>{{ $product['kodproduk'] . ' / ' . $product['description'] }}</td>
|
||||
<td>{{ $product['product_code'] ?? '' }}</td>
|
||||
<td>5</td>
|
||||
<td>Nilai</td>
|
||||
<td>{{ 'RM ' . number_format($gadai_detail['pinjaman'],2) }}</td>
|
||||
|
||||
@@ -620,7 +620,7 @@
|
||||
<tr>
|
||||
<td class="text-center">2</td>
|
||||
<td>Kod Produk / Deskripsi</td>
|
||||
<td>{{ $product['kodproduk'] . ' / ' . $product['description'] }}</td>
|
||||
<td>{{ $product['product_code'] ?? '' }}</td>
|
||||
<td class="text-center">5</td>
|
||||
<td>harga kos</td>
|
||||
<td>{{ 'RM' . number_format($gadai_detail['pinjaman'], 2) }}</td>
|
||||
@@ -1854,7 +1854,7 @@
|
||||
<tr>
|
||||
<td class="text-center">2</td>
|
||||
<td>Kod Produk / Deskripsi</td>
|
||||
<td>{{ $product['kodproduk'] . ' / ' . $product['description'] }}</td>
|
||||
<td>{{ $product['product_code'] ?? '' }}</td>
|
||||
<td class="text-center">5</td>
|
||||
<td>Harga Kos</td>
|
||||
<td>{{ 'RM' . number_format($gadai_detail['pinjaman'], 2) }}</td>
|
||||
@@ -2112,6 +2112,7 @@
|
||||
</div>
|
||||
<div class="main-page" style="font-family: Arial, Helvetica, sans-serif;">
|
||||
<div class="sub-page" style="font-size: 11px;">
|
||||
@if ($pembiayaanOnlineEnabled ?? false)
|
||||
@php
|
||||
$caraTerimaBayaran = strtoupper(trim((string) ($gadai_detail['cara_terima'] ?? '')));
|
||||
@endphp
|
||||
@@ -2128,6 +2129,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
{{-- HEADER SECTION --}}
|
||||
<table style="width: 100%; margin-top: 0;">
|
||||
<tr style="vertical-align: top;">
|
||||
|
||||
+15
-1
@@ -17,6 +17,8 @@ use Illuminate\Support\Facades\Storage;
|
||||
|
||||
Route::post('/internal/notifications', ['as' => 'internal.notifications.store', 'uses' => 'InternalNotificationController@store']);
|
||||
|
||||
Route::view('/dasar-privasi', 'dasar-privasi')->name('dasar.privasi');
|
||||
|
||||
Route::get('/health', function () {
|
||||
return response()->json(['status' => 'ok']);
|
||||
});
|
||||
@@ -61,7 +63,13 @@ Route::get('test', function () {
|
||||
return "event test je";
|
||||
});
|
||||
|
||||
Route::get('logs', '\Rap2hpoutre\LaravelLogViewer\LogViewerController@index');
|
||||
Route::get('logs', '\Rap2hpoutre\LaravelLogViewer\LogViewerController@index')
|
||||
->middleware([
|
||||
'auth',
|
||||
'role:admin,masteradmin,operasi',
|
||||
'throttle:10,1',
|
||||
\App\Http\Middleware\LogViewerPassword::class,
|
||||
]);
|
||||
Route::get('change-password', ['as'=>'user.password','uses'=>'ChangePasswordController@index']);
|
||||
Route::post('change-password', ['as'=>'change.password','uses'=>'ChangePasswordController@store']);
|
||||
|
||||
@@ -204,6 +212,7 @@ Route::put('/pembiayaan-online/pc/lines/{id}',['as'=>'pembiayaan.online.pc.updat
|
||||
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}/borang',['as'=>'pembiayaan.online.pc.borang','uses'=>'PembiayaanOnlineController@viewBorang'])->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::get('/pembiayaan-online/pc/batches/{batchId}',['as'=>'pembiayaan.online.pc.batch','uses'=>'PembiayaanOnlineController@showBatch'])->middleware('auth','khazanah');
|
||||
@@ -230,6 +239,7 @@ Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/approve',['as
|
||||
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::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}/borang',['as'=>'pembiayaan.online.operasi.borang','uses'=>'PembiayaanOnlineController@operasiViewBorang'])->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::post('/permohonan/simpan',['as'=>'permohonan.simpan','uses' => 'KhazanahController@SimpanPermohonan'])->middleware('auth','khazanah');
|
||||
@@ -243,6 +253,8 @@ Route::post('/kakitangan/harian',['as'=>'kakitangan.harian','uses'=>'KakitanganC
|
||||
Route::get('/lelong',['as'=>'lelong','uses'=>'LelongController@lelong']);
|
||||
|
||||
Route::get('/khazanah/harga_emas',['as'=>'khazanah.harga_emas','uses'=>'HargaEmasController@index'])->middleware('auth','khazanah');
|
||||
Route::get('/khazanah/komoditi/bsas',['as'=>'khazanah.bsas','uses'=>'KomuditiController@khazanahBsas'])->middleware('auth','khazanah');
|
||||
Route::get('/khazanah/komoditi/bsas/ecert/{uuid}',['as'=>'khazanah.bsas.ecert','uses'=>'KomuditiController@showBsasEcert'])->middleware('auth','khazanah');
|
||||
|
||||
//Request Teller Batal Route
|
||||
Route::get('/requestbatal',['as'=>'request.pembatalan','uses'=>'KhazanahController@RequestPembatalan'])->middleware('auth','khazanah');
|
||||
@@ -445,6 +457,8 @@ Route::get('/operasi/marginmutu/edit',['as'=>'operasi.marginmutu.edit','uses'=>'
|
||||
Route::get('/komoditi',['as'=>'komuditi','uses'=>'KomuditiController@index']);
|
||||
Route::get('/komoditi/rekod',['as'=>'rekod.komoditi','uses'=>'KomuditiController@rekodKomoditi']);
|
||||
Route::get('/komoditi/rekod/print',['as'=>'komoditi.rekod.print','uses'=>'KomuditiController@printRekodTransaksi']);
|
||||
Route::get('/komoditi/bsas/ecert/preview',['as'=>'komoditi.bsas.ecert.preview','uses'=>'KomuditiController@previewBsasEcert'])->middleware('auth','operasi');
|
||||
Route::get('/komoditi/bsas/ecert/{uuid}',['as'=>'komoditi.bsas.ecert','uses'=>'KomuditiController@showBsasEcert'])->middleware('auth','operasi');
|
||||
|
||||
Route::post('/khazanah/suratakuangadaian',['as'=>'agh.create','uses'=>'KhazanahController@SuratAkuanGadaian'])->middleware('auth','khazanah');
|
||||
Route::post('/khazanah/suratakuangadaianedit',['as'=>'agh.update','uses'=>'KhazanahController@SuratAkuanGadaianUpdate'])->middleware('auth','khazanah');
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Http\Middleware\LogViewerPassword;
|
||||
use Illuminate\Http\Request;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LogViewerPasswordTest extends TestCase
|
||||
{
|
||||
public function test_missing_configuration_denies_access()
|
||||
{
|
||||
config(['logviewer.password' => null]);
|
||||
$response = $this->checkAccess();
|
||||
$this->assertSame(503, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_missing_or_incorrect_credentials_are_rejected()
|
||||
{
|
||||
config(['logviewer.password' => password_hash('test-only-secret', PASSWORD_DEFAULT)]);
|
||||
foreach ([[], ['PHP_AUTH_USER' => 'logs', 'PHP_AUTH_PW' => 'wrong'],
|
||||
['PHP_AUTH_USER' => 'other', 'PHP_AUTH_PW' => 'test-only-secret']] as $server) {
|
||||
$response = $this->checkAccess($server);
|
||||
$this->assertSame(401, $response->getStatusCode());
|
||||
$this->assertStringContainsString('Basic realm=', $response->headers->get('WWW-Authenticate'));
|
||||
}
|
||||
}
|
||||
|
||||
public function test_correct_credentials_allow_access_without_caching()
|
||||
{
|
||||
config(['logviewer.password' => password_hash('test-only-secret', PASSWORD_DEFAULT)]);
|
||||
$response = $this->checkAccess(['PHP_AUTH_USER' => 'logs', 'PHP_AUTH_PW' => 'test-only-secret']);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertSame('allowed', $response->getContent());
|
||||
$this->assertStringContainsString('no-store', $response->headers->get('Cache-Control'));
|
||||
}
|
||||
|
||||
public function test_logs_route_has_auth_role_password_and_throttle_middleware()
|
||||
{
|
||||
$route = app('router')->getRoutes()->match(Request::create('/logs'));
|
||||
$middleware = $route->gatherMiddleware();
|
||||
$this->assertContains('auth', $middleware);
|
||||
$this->assertContains('role:admin,masteradmin', $middleware);
|
||||
$this->assertContains(LogViewerPassword::class, $middleware);
|
||||
$this->assertContains('throttle:10,1', $middleware);
|
||||
}
|
||||
|
||||
private function checkAccess(array $server = [])
|
||||
{
|
||||
$request = Request::create('/logs?dl=example', 'GET', [], [], [], $server);
|
||||
return (new LogViewerPassword)->handle($request, function () {
|
||||
return response('allowed');
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user