DONE: confirmation and list online form

This commit is contained in:
ISMAIL MASSERAN
2026-09-03 15:34:52 +08:00
parent 6f4507dc08
commit effe268e3b
15 changed files with 1976 additions and 87 deletions
+115
View File
@@ -259,6 +259,121 @@ class GadaianController extends Controller
return redirect()->route('customer_info');
}
public function printBorangPengesahanOnline($norujukan)
{
$auth_user = Auth::user();
$kodcaw = $auth_user['cawangan'];
$onlineResp = Http::withOptions(['verify' => config('app.api_verify')])
->get(config('api.url') . '/api/pembiayaan-online/' . $kodcaw . '/by-norujukan/' . $norujukan);
if (!$onlineResp->successful()) {
abort(404, 'Pembiayaan online tidak dijumpai.');
}
$line = $onlineResp->json();
if (!is_array($line) || empty($line['norujukan'])) {
abort(404, 'Pembiayaan online tidak dijumpai.');
}
return $this->renderBorangPengesahanOnline($line, $kodcaw);
}
public function previewBorangPengesahanOnline(Request $request)
{
$auth_user = Auth::user();
$kodcaw = $auth_user['cawangan'];
$line = [
'norujukan' => $request->input('norujukan'),
'nokp' => $request->input('nokp'),
'nopelanggan' => $request->input('nopelanggan'),
'nama_pelanggan' => $request->input('nama_pelanggan'),
'pinjaman' => $request->input('pinjaman'),
'kodbank' => $request->input('kodbank'),
'nama_bank' => $request->input('nama_bank'),
'noakaun' => $request->input('noakaun'),
'nama_akaun' => $request->input('nama_akaun'),
'created_by' => $auth_user['name'] ?? '',
'created_at' => Carbon::now()->toDateTimeString(),
];
if (empty($line['norujukan']) || empty($line['noakaun'])) {
abort(422, 'Sila lengkapkan maklumat bank sebelum cetak borang.');
}
return $this->renderBorangPengesahanOnline($line, $kodcaw);
}
private function renderBorangPengesahanOnline(array $line, $kodcaw)
{
$auth_user = Auth::user();
$cawanganResp = Http::withOptions(['verify' => config('app.api_verify')])
->get(config('api.url') . '/api/cawangan/detail/' . $kodcaw)
->json();
$cawangan_detail = (is_array($cawanganResp) && isset($cawanganResp[0]))
? $cawanganResp[0]
: (is_array($cawanganResp) ? $cawanganResp : []);
$nokpRaw = $line['nokp'] ?? '';
$customer = [];
if ($nokpRaw !== '') {
$customerResp = Http::withOptions(['verify' => config('app.api_verify')])
->get(config('api.url') . '/api/customers/' . $nokpRaw)
->json();
if (is_array($customerResp)) {
$customer = $customerResp;
}
}
$cawangan = $cawangan_detail['namacaw']
?? $cawangan_detail['details_caw']
?? $kodcaw;
$alamat1 = $cawangan_detail['alamat1'] ?? '';
$alamat2 = $cawangan_detail['alamat2'] ?? '';
$notel = $cawangan_detail['notel'] ?? '';
$nama = $line['nama_pelanggan'] ?? ($customer['nama'] ?? '');
$nokp = !empty($customer['kpbaru']) ? $customer['kpbaru'] : ($customer['kplama'] ?? $nokpRaw);
$nopelanggan = $line['nopelanggan'] ?? ($customer['nopelanggan'] ?? '');
$telefon = $customer['telefon'] ?? '';
$teller = $line['created_by'] ?? ($auth_user['name'] ?? '');
$bank = $line['nama_bank'] ?? ($line['kodbank'] ?? '');
$noakaun = $line['noakaun'] ?? '';
$nama_akaun = $line['nama_akaun'] ?? $nama;
$pinjaman = number_format((float) ($line['pinjaman'] ?? 0), 2);
$norujukan = $line['norujukan'] ?? '';
$tarikhSumber = $line['created_at'] ?? null;
try {
$tarikh = $tarikhSumber
? Carbon::parse($tarikhSumber)->format('d/m/Y')
: Carbon::now()->format('d/m/Y');
} catch (\Exception $e) {
$tarikh = Carbon::now()->format('d/m/Y');
}
return view('print.borang_pengesahan_online', compact(
'cawangan',
'kodcaw',
'alamat1',
'alamat2',
'notel',
'norujukan',
'tarikh',
'teller',
'nama',
'nokp',
'nopelanggan',
'telefon',
'pinjaman',
'bank',
'noakaun',
'nama_akaun'
));
}
public function editstore(Request $request)
{
$auth_user = Auth::user();
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
@@ -346,6 +347,98 @@ class PembiayaanOnlineController extends Controller
]);
}
/**
* Operasi: printable batch kelulusan form.
*/
public function operasiPrintBatch($kodcaw, $batchId)
{
$api_url = config('api.url');
$detail = $this->api()
->get($api_url . '/api/pembiayaan-online/operasi/' . $kodcaw . '/batches/' . $batchId)
->json();
if (!is_array($detail) || empty($detail['batch'])) {
return redirect()
->route('pembiayaan.online.operasi')
->with('error', 'Batch tidak dijumpai.');
}
$batch = $detail['batch'];
$lines = $detail['lines'] ?? [];
if (!is_array($lines)) {
$lines = [];
}
$cawanganResp = $this->api()
->get($api_url . '/api/cawangan/detail/' . $kodcaw)
->json();
$cawangan_detail = (is_array($cawanganResp) && isset($cawanganResp[0]))
? $cawanganResp[0]
: (is_array($cawanganResp) ? $cawanganResp : []);
$cawangan = $cawangan_detail['namacaw']
?? $cawangan_detail['details_caw']
?? $cawangan_detail['nama']
?? $kodcaw;
$alamat1 = $cawangan_detail['alamat1'] ?? '';
$alamat2 = $cawangan_detail['alamat2'] ?? '';
$notel = $cawangan_detail['notel'] ?? '';
$batchNo = $batch['batch_no'] ?? '-';
$slot = $batch['slot'] ?? '-';
$status = $batch['status'] ?? '-';
$dihantarOleh = $batch['pc_submitted_by'] ?? '-';
$jumlah = (float) ($batch['jumlah_keseluruhan'] ?? 0);
if ($jumlah <= 0 && count($lines) > 0) {
$jumlah = (float) collect($lines)->sum(function ($line) {
return (float) ($line['pinjaman'] ?? 0);
});
}
$opsBy = Auth::user()['name'] ?? '';
foreach ($lines as $line) {
if (!empty($line['ops_by'])) {
$opsBy = $line['ops_by'];
break;
}
}
$tarikh = $this->formatPrintDate($batch['tarikh'] ?? null);
$dihantarPada = $this->formatPrintDate($batch['submitted_at'] ?? null, true);
return view('print.borang_batch_pembiayaan_online', compact(
'cawangan',
'kodcaw',
'alamat1',
'alamat2',
'notel',
'tarikh',
'batchNo',
'slot',
'status',
'dihantarOleh',
'dihantarPada',
'opsBy',
'lines',
'jumlah'
));
}
protected function formatPrintDate($value, $withTime = false)
{
if ($value === null || $value === '' || $value === '-') {
return '-';
}
try {
return Carbon::parse($value)->format($withTime ? 'd/m/Y H:i' : 'd/m/Y');
} catch (\Exception $e) {
return (string) $value;
}
}
public function operasiApproveLine(Request $request, $kodcaw, $id)
{
$res = $this->api()
@@ -0,0 +1,137 @@
@props([
'id',
'columns' => [],
'exportable' => true,
'filename' => '',
'skipExport' => ['Bil', 'Cetak'],
])
<style>
.erahn-datatable {
width: 100%;
max-width: 100%;
}
.erahn-datatable .dataTables_wrapper {
width: 100%;
overflow-x: auto;
}
.erahn-datatable table {
width: 100% !important;
margin: 0;
}
.erahn-datatable table th,
.erahn-datatable table td {
white-space: nowrap;
vertical-align: middle;
}
.erahn-datatable .dt-buttons {
margin: 0 0 8px 8px;
}
.erahn-datatable .dt-button {
border: 0;
border-radius: 4px;
padding: 6px 12px;
margin-left: 4px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
background: #17a2b8;
color: #fff;
}
.erahn-datatable .dt-button:hover {
opacity: 0.9;
}
.erahn-datatable .buttons-excel {
background: #28a745;
}
.erahn-datatable .buttons-csv {
background: #6c757d;
}
</style>
<script>
if (typeof window.initErahnDatatable !== 'function') {
window.initErahnDatatable = function (selector, options) {
var $table = $(selector);
var exportable = $table.data('exportable');
var filename = $table.data('export-filename') || $table.attr('id') || 'export';
var defaults = {
scrollX: true,
autoWidth: false,
language: {
emptyTable: 'Tiada rekod'
}
};
if ((exportable === undefined || exportable === 1 || exportable === true) &&
$.fn.dataTable && $.fn.dataTable.Buttons) {
defaults.dom = 'lBfrtip';
defaults.buttons = [
{
extend: 'excelHtml5',
text: 'Excel',
className: 'buttons-excel',
title: filename,
filename: filename,
exportOptions: {
columns: ':not(.no-export)',
format: {
body: function (data) {
return $('<div>').html(data).text().replace(/\s+/g, ' ').trim();
}
}
}
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'buttons-csv',
bom: true,
title: filename,
filename: filename,
exportOptions: {
columns: ':not(.no-export)',
format: {
body: function (data) {
return $('<div>').html(data).text().replace(/\s+/g, ' ').trim();
}
}
}
}
];
}
return $table.DataTable($.extend(true, {}, defaults, options || {}));
};
}
if (typeof window.adjustErahnDatatables !== 'function') {
window.adjustErahnDatatables = function () {
if (!$.fn.dataTable) {
return;
}
setTimeout(function () {
$.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();
}, 50);
};
}
</script>
<div class="erahn-datatable">
<table
id="{{ $id }}"
{{ $attributes->merge(['class' => 'table table-striped table-hover nowrap']) }}
style="width:100%"
data-exportable="{{ $exportable ? 1 : 0 }}"
data-export-filename="{{ $filename !== '' ? $filename : $id }}"
>
<thead class="thead-dark">
<tr>
@foreach ($columns as $column)
<th @if(in_array($column, $skipExport, true)) class="no-export" @endif>{{ $column }}</th>
@endforeach
</tr>
</thead>
<tbody></tbody>
{{ $slot }}
</table>
</div>
@@ -0,0 +1,44 @@
@props([
'showCopies' => true,
])
<style>
.print-footer {
margin-top: 14px;
font-family: Arial, Helvetica, sans-serif;
color: #222;
}
.print-footer .copies {
margin-top: 10px;
font-size: 10px;
}
.print-footer .copies span {
display: inline-block;
border: 1px solid #111;
width: 11px;
height: 11px;
margin-right: 4px;
vertical-align: -1px;
}
.print-footer .notes {
margin-top: 10px;
font-size: 9.5px;
line-height: 1.45;
}
.print-footer .notes b { font-size: 10px; }
.print-footer .notes p { margin: 2px 0; }
</style>
<div {{ $attributes->merge(['class' => 'print-footer']) }}>
@if($showCopies)
<div class="copies">
Salinan: <span></span> Kad Pengenalan &nbsp;&nbsp; <span></span> Akaun Bank/ Slip/ Penyata Bank
</div>
@endif
@if(trim($slot) !== '')
<div class="notes">
{{ $slot }}
</div>
@endif
</div>
@@ -0,0 +1,101 @@
@props([
'cawangan' => '',
'kodcaw' => '',
'alamat1' => '',
'alamat2' => '',
'notel' => '',
'tarikh' => '',
'norujukan' => '',
'rujukanLabel' => 'No. Rujukan SAG',
'showDummyBadge' => false,
])
<style>
.print-header {
display: grid;
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
align-items: start;
column-gap: 12px;
border-bottom: 2px solid #111;
padding-bottom: 8px;
font-family: Arial, Helvetica, sans-serif;
color: #111;
}
.print-header .org {
min-width: 0;
}
.print-header .org p {
margin: 0;
font-size: 10px;
line-height: 1.35;
}
.print-header .org .name {
font-size: 11px;
font-weight: bold;
}
.print-header .logos {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding-top: 2px;
}
.print-header .logos img {
display: block;
height: 40px;
width: auto;
max-width: 70px;
object-fit: contain;
}
.print-header .meta {
text-align: right;
font-size: 10px;
line-height: 1.4;
}
.print-header .meta .label { color: #444; }
.print-header .dummy-badge {
display: inline-block;
margin-top: 4px;
padding: 1px 6px;
border: 1px solid #c0392b;
color: #c0392b;
font-size: 9px;
font-weight: bold;
letter-spacing: 0.08em;
}
@media print {
.print-header .dummy-badge { display: none !important; }
}
</style>
<div {{ $attributes->merge(['class' => 'print-header']) }}>
<div class="org">
<p class="name">KOPERASI PERMODALAN KELANTAN BERHAD (D-5-0228)</p>
<p>Ar-Rahn {{ $cawangan }}</p>
<p>{{ $alamat1 }}</p>
<p>{{ $alamat2 }}</p>
<p>Tel: {{ $notel }}</p>
</div>
<div class="logos">
<img src="{{ asset('img/kopkb.png') }}" alt="KPKB">
<img src="{{ asset('img/logo-arrahn.jpeg') }}" alt="Ar-Rahn">
</div>
<div class="meta">
@if($kodcaw || $cawangan)
<div>
<span class="label">Cawangan</span><br>
<b>{{ trim(implode(' — ', array_filter([$kodcaw, $cawangan]))) }}</b>
</div>
@endif
@if($tarikh)
<div style="{{ ($kodcaw || $cawangan) ? 'margin-top:6px' : '' }}"><span class="label">Tarikh</span><br><b>{{ $tarikh }}</b></div>
@endif
@if($norujukan)
<div style="margin-top:6px"><span class="label">{{ $rujukanLabel }}</span><br><b>{{ $norujukan }}</b></div>
@endif
{{ $slot }}
@if($showDummyBadge)
<div class="dummy-badge">CONTOH SAHAJA</div>
@endif
</div>
</div>
@@ -0,0 +1,25 @@
<style>
.print-watermark {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
pointer-events: none;
z-index: 0;
}
.print-watermark img {
height: 160px;
max-width: 240px;
object-fit: contain;
opacity: 0.12;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
</style>
<div class="print-watermark" aria-hidden="true">
<img src="{{ asset('img/logo_kad.jpeg') }}" alt="">
<img src="{{ asset('img/logo-arrahn.jpeg') }}" alt="">
</div>
@@ -21,6 +21,10 @@
</ol>
</nav>
@if(session()->has('message'))
<div class="alert alert-success">{{ session('message') }}</div>
@endif
@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">
+88 -87
View File
@@ -22,6 +22,10 @@
</ol>
</nav>
@if(session()->has('message'))
<div class="alert alert-success">{{ session('message') }}</div>
@endif
@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">
@@ -359,7 +363,7 @@
</div>
<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';
@@ -378,91 +382,41 @@
</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">
<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>
</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', 'Borang Online']"
/>
</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">
<thead class="thead-dark">
{{-- <tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Gadai</th>
<th>Tarikh Matang</th>
<th>Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
<th>Lelong</th>
</tr> --}}
<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>
</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', 'Borang Online']"
/>
</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']"
/>
<table id="lelongTable" class="table table-striped table-hover">
<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>
<th>Status Tuntutan</th>
<th>Cetak</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', 'Status Tuntutan', 'Cetak']"
/>
<div class="text-center">
<button class="btn btn-primary" onclick="ubahfunc(this)" id="button-edit-gadaian">Ubah</button>
<button class="btn btn-primary" onclick="hapusfunc()">Hapus</button>
<button class="btn btn-primary" onclick="histfunc()">Rekod Pembiayaan</button>
<button class="btn btn-primary" onclick="removeansuran(this)" id="button-remove-ansuran">Hapus Ansuran</button>
<button class="btn btn-info" type="button" onclick="cetakBorangOnlineSelected()">Cetak Borang Online</button>
</div>
</div>
@@ -787,27 +741,32 @@
}
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
// here is the new selected tab id
var selectedTabId = e.target.id;
$('a[data-toggle="tab"]').on('shown.bs.tab', function () {
if (typeof adjustErahnDatatables === 'function') {
adjustErahnDatatables();
}
});
var tablegadai = $('#myTable').DataTable({
"scrollX": false,
order: [
[1, 'desc']
var tablegadai = initErahnDatatable('#myTable', {
order: [[1, 'desc']],
columnDefs: [
{ targets: 0, orderable: false, width: '40px' },
{ targets: -1, orderable: false, searchable: false, width: '70px' }
]
});
var xtawarruq = $('#xtawarruq').DataTable({
"scrollX": false
var xtawarruq = initErahnDatatable('#xtawarruq', {
columnDefs: [
{ targets: 0, orderable: false, width: '40px' }
]
});
var tabledahtebus = $('#dahtebusTable').DataTable({});
var tabledahtebus = initErahnDatatable('#dahtebusTable');
var tablelelong = $('#lelongTable').DataTable({
"scrollX": false
var tablelelong = initErahnDatatable('#lelongTable', {
columnDefs: [
{ targets: -1, orderable: false, searchable: false, width: '80px' }
]
});
var historybayarandatatable = $('#tablehistorybayaran').DataTable({
@@ -822,6 +781,41 @@
minimumFractionDigits: 2
});
function urlBorangOnline(norujukan) {
return '{{ url("/gadai/borang-pengesahan-online") }}/' + encodeURIComponent(norujukan);
}
function cetakBorangOnlineCell(gadai_detail) {
var cara = String(gadai_detail['cara_terima'] || '').toUpperCase();
if (cara !== 'ONLINE') {
return '';
}
return '<a class="btn btn-sm btn-info" href="' + urlBorangOnline(gadai_detail['norujukan']) +
'" target="_blank" title="Cetak borang pengesahan online"><i class="fas fa-print"></i></a>';
}
function cetakBorangOnlineSelected() {
var selected = $('input[name="belum"]:checked');
if (!selected.length) {
Swal.fire({
icon: 'warning',
title: 'Sila pilih SAG',
text: 'Pilih pembiayaan untuk cetak borang pengesahan.'
});
return;
}
var cara = String(selected.data('cara-terima') || '').toUpperCase();
if (cara !== 'ONLINE') {
Swal.fire({
icon: 'info',
title: 'Bukan pembiayaan online',
text: 'Borang ini hanya untuk SAG yang terima pembiayaan secara online.'
});
return;
}
window.open(urlBorangOnline(selected.val()), '_blank');
}
function getGadaiByNorujukan(norujukan) {
console.log(norujukan);
let gadai_tawarruq = fetch(api_url + '/api/gadai/norujukan/' + norujukan);
@@ -1223,8 +1217,8 @@
let table_norujukan = gadai_detail["norujukan"];
tablegadai.row.add([
'<input type="radio" value=' + gadai_detail["norujukan"] +
' name="belum"/>',
'<input type="radio" value="' + gadai_detail["norujukan"] +
'" name="belum" data-cara-terima="' + (gadai_detail['cara_terima'] || '') + '"/>',
'<a href="#" onclick="checkserah(this)" data-pinjaman=' +
gadai_detail['pinjaman'] + ' data-hargajualan=' +
gadai_detail['hargajualan'] + ' data-norujukan=' +
@@ -1241,6 +1235,7 @@
'RM ' + formatter.format(upahsemasa['pendapatan']),
'<div style="white-space: nowrap; color:red; font-weight: bolder">' +
taglel + '</div>',
cetakBorangOnlineCell(gadai_detail),
]).draw();
}
} else if (jenistebus == "sudah_tebus") {
@@ -1560,6 +1555,9 @@
success: function(data) {
$('#myTable').parents('div.dataTables_wrapper').first().show();
gadaiTable(data, "belum_tebus");
if (typeof adjustErahnDatatables === 'function') {
adjustErahnDatatables();
}
}
});
@@ -2816,6 +2814,9 @@
url: api_url + "/api/customers/" + noic + "/gadai/belum_tebus/" + kodcaw,
success: function(data) {
gadaiTable(data, "belum_tebus");
if (typeof adjustErahnDatatables === 'function') {
adjustErahnDatatables();
}
}
});
}
@@ -0,0 +1,354 @@
<!DOCTYPE html>
<html lang="ms">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dummy Borang Kelulusan Batch Pembiayaan Online</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #e8eaed;
font-family: Arial, Helvetica, sans-serif;
color: #111;
}
.toolbar {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 16px;
background: #1f3a5f;
color: #fff;
font-size: 13px;
}
.toolbar b { letter-spacing: 0.04em; }
.toolbar .hint { opacity: 0.85; }
.toolbar button {
border: 0;
background: #fff;
color: #1f3a5f;
font-weight: bold;
padding: 8px 16px;
cursor: pointer;
border-radius: 3px;
}
.sheet-wrap {
padding: 24px 0 48px;
}
.sheet {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
background: #fff;
padding: 14mm 12mm 16mm;
box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.title {
text-align: center;
margin: 14px 0 4px;
}
.title h1 {
margin: 0;
font-size: 14px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.title p {
margin: 4px 0 0;
font-size: 10px;
color: #333;
}
.section {
margin-top: 12px;
}
.section-title {
font-size: 11px;
font-weight: bold;
background: #eef1f4;
border: 1px solid #111;
border-bottom: 0;
padding: 5px 8px;
text-transform: uppercase;
}
table.fields {
width: 100%;
border-collapse: collapse;
font-size: 11px;
}
table.fields th,
table.fields td {
border: 1px solid #111;
padding: 6px 8px;
vertical-align: top;
text-align: left;
}
table.fields th {
width: 22%;
font-weight: normal;
background: #fafbfc;
color: #222;
}
table.fields td.amt {
font-size: 14px;
font-weight: bold;
letter-spacing: 0.02em;
}
table.lines {
width: 100%;
border-collapse: collapse;
font-size: 9.5px;
}
table.lines th,
table.lines td {
border: 1px solid #111;
padding: 4px 5px;
vertical-align: top;
}
table.lines thead th {
background: #eef1f4;
font-weight: bold;
text-align: center;
text-transform: uppercase;
font-size: 8.5px;
letter-spacing: 0.02em;
}
table.lines td.num { text-align: center; }
table.lines td.amt { text-align: right; white-space: nowrap; }
table.lines tfoot td {
font-weight: bold;
background: #fafbfc;
}
.akuan {
font-size: 11px;
line-height: 1.55;
border: 1px solid #111;
padding: 10px 12px;
}
.akuan ol {
margin: 6px 0 0;
padding-left: 18px;
}
.akuan li { margin-bottom: 4px; }
.signs {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 16px;
}
.sign-box {
border: 1px solid #111;
min-height: 160px;
padding: 8px 10px;
font-size: 10px;
}
.sign-box .role {
font-weight: bold;
text-align: center;
text-transform: uppercase;
border-bottom: 1px solid #ccc;
padding-bottom: 4px;
margin-bottom: 8px;
}
.sign-line {
margin-top: 72px;
border-top: 1px solid #111;
padding-top: 6px;
}
.sign-line p { margin: 2px 0; }
@page {
size: A4;
margin: 10mm;
}
@media print {
body { background: #fff; }
.toolbar { display: none !important; }
.sheet-wrap { padding: 0; }
.sheet {
width: auto;
min-height: 0;
margin: 0;
padding: 0;
box-shadow: none;
}
}
</style>
</head>
<body>
@php
$cawangan = 'KOTA BHARU 2';
$kodcaw = 'KB2';
$alamat1 = 'Lot 123, Jalan Sultan Yahya Petra';
$alamat2 = '15200 Kota Bharu, Kelantan';
$notel = '09-123 4567';
$tarikh = '03/09/2026';
$batchNo = 'KB2-PO-20260903-B1-001';
$slot = 'BATCH1';
$status = 'SUBMITTED';
$dihantarOleh = 'NUR AINA BINTI HASSAN';
$dihantarPada = '03/09/2026 10:42';
$opsBy = 'MOHD FAIZ BIN ISMAIL';
$lines = [
['norujukan' => 'KB2-260903-0001', 'nama' => 'AHMAD BIN ABDULLAH', 'nokp' => '900101-03-1234', 'bank' => 'MAYBANK', 'noakaun' => '123456789012', 'nama_akaun' => 'AHMAD BIN ABDULLAH', 'pinjaman' => 15000.00],
['norujukan' => 'KB2-260903-0004', 'nama' => 'SITI MARIAM BINTI YUSOF', 'nokp' => '850215-03-5678', 'bank' => 'CIMB', 'noakaun' => '800123456789', 'nama_akaun' => 'SITI MARIAM BINTI YUSOF', 'pinjaman' => 8200.50],
['norujukan' => 'KB2-260903-0007', 'nama' => 'MOHD RAZAK BIN ALI', 'nokp' => '780930-03-1122', 'bank' => 'BANK ISLAM', 'noakaun' => '140234567890', 'nama_akaun' => 'MOHD RAZAK BIN ALI', 'pinjaman' => 5000.00],
['norujukan' => 'KB2-260903-0010', 'nama' => 'FATIMAH BINTI OMAR', 'nokp' => '920408-03-3344', 'bank' => 'RHB', 'noakaun' => '212345678901', 'nama_akaun' => 'FATIMAH BINTI OMAR', 'pinjaman' => 12500.00],
['norujukan' => 'KB2-260903-0012', 'nama' => 'HASSAN BIN IBRAHIM', 'nokp' => '700112-03-5566', 'bank' => 'MAYBANK', 'noakaun' => '156789012345', 'nama_akaun' => 'HASSAN BIN IBRAHIM', 'pinjaman' => 3400.00],
];
$jumlah = array_sum(array_column($lines, 'pinjaman'));
@endphp
<div class="toolbar">
<div>
<b>DUMMY FORM</b>
<span class="hint"> reka bentuk borang kelulusan batch pembiayaan online (Operasi). Data ini contoh sahaja.</span>
</div>
<button type="button" onclick="window.print()">Cetak / Pratinjau</button>
</div>
<div class="sheet-wrap">
<div class="sheet">
<x-print.header
:cawangan="$cawangan"
:kodcaw="$kodcaw"
:alamat1="$alamat1"
:alamat2="$alamat2"
:notel="$notel"
:tarikh="$tarikh"
:norujukan="$batchNo"
rujukan-label="No. Batch"
:show-dummy-badge="true"
/>
<div class="title">
<h1>Borang Kelulusan Pembiayaan Online<br>Senarai Batch Pembayaran</h1>
<p>Untuk semakan Operasi dan kelulusan Pengurus Besar. Bukan untuk tandatangan pelanggan.</p>
</div>
<div class="section">
<div class="section-title">A. Maklumat Batch</div>
<table class="fields">
<tr>
<th>No. Batch</th>
<td>{{ $batchNo }}</td>
<th>Cawangan</th>
<td>{{ $kodcaw }} {{ $cawangan }}</td>
</tr>
<tr>
<th>Tarikh / Slot</th>
<td>{{ $tarikh }} &nbsp;·&nbsp; {{ $slot }}</td>
<th>Status Batch</th>
<td>{{ $status }}</td>
</tr>
<tr>
<th>Dihantar Oleh (PC)</th>
<td>{{ $dihantarOleh }}</td>
<th>Dihantar Pada</th>
<td>{{ $dihantarPada }}</td>
</tr>
<tr>
<th>Bilangan Rekod</th>
<td>{{ count($lines) }}</td>
<th>Jumlah Keseluruhan</th>
<td class="amt">RM {{ number_format($jumlah, 2) }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">B. Senarai Penerima Dalam Batch</div>
<table class="lines">
<thead>
<tr>
<th style="width:4%">Bil</th>
<th style="width:14%">No. SAG</th>
<th>Pelanggan</th>
<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 style="width:12%">Pinjaman (RM)</th>
</tr>
</thead>
<tbody>
@foreach($lines as $i => $line)
<tr>
<td class="num">{{ $i + 1 }}</td>
<td class="num">{{ $line['norujukan'] }}</td>
<td>{{ $line['nama'] }}</td>
<td class="num">{{ $line['nokp'] }}</td>
<td>{{ $line['bank'] }}</td>
<td class="num">{{ $line['noakaun'] }}</td>
<td>{{ $line['nama_akaun'] }}</td>
<td class="amt">{{ number_format($line['pinjaman'], 2) }}</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align:right">JUMLAH</td>
<td class="amt">{{ number_format($jumlah, 2) }}</td>
</tr>
</tfoot>
</table>
</div>
<div class="section">
<div class="section-title">C. Pengesahan Operasi</div>
<div class="akuan">
Dengan ini disahkan bahawa senarai di Bahagian B telah disemak dan amaun pembiayaan
sebanyak <b>RM {{ number_format($jumlah, 2) }}</b> ({{ count($lines) }} rekod)
bagi batch <b>{{ $batchNo }}</b> cawangan <b>{{ $cawangan }}</b> adalah lengkap
untuk proses pembayaran ke akaun bank pelanggan.
<ol>
<li>Maklumat SAG, nama, no. KP, bank dan no. akaun telah disemak terhadap rekod sistem.</li>
<li>Pembayaran akan dikreditkan ke akaun penerima seperti senarai, bukan tunai di kaunter.</li>
<li>Sebarang ralat akaun yang dikesan selepas kelulusan hendaklah dilaporkan serta-merta.</li>
</ol>
</div>
</div>
<div class="signs">
<div class="sign-box">
<div class="role">Tandatangan Operasi</div>
<div class="sign-line">
<p>Nama: {{ $opsBy }}</p>
<p>Jawatan: Operasi</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Pengurus Besar</div>
<div class="sign-line">
<p>Nama:</p>
<p>Cop / Paraf:</p>
<p>Tarikh:</p>
</div>
</div>
</div>
<x-print.footer :show-copies="false">
<b>Nota:</b>
<p>1. Borang ini dicetak dari skrin Operasi Pembiayaan Online (Batch) untuk kelulusan pembayaran.</p>
<p>2. Hanya dua tandatangan diperlukan: Operasi dan Pengurus Besar.</p>
<p>3. Simpan salinan bersama bukti pindahan bank selepas status PAID.</p>
</x-print.footer>
</div>
</div>
</body>
</html>
@@ -0,0 +1,322 @@
<!DOCTYPE html>
<html lang="ms">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dummy Borang Pengesahan Pembiayaan Online</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #e8eaed;
font-family: Arial, Helvetica, sans-serif;
color: #111;
}
.toolbar {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 16px;
background: #1f3a5f;
color: #fff;
font-size: 13px;
}
.toolbar b { letter-spacing: 0.04em; }
.toolbar .hint { opacity: 0.85; }
.toolbar button {
border: 0;
background: #fff;
color: #1f3a5f;
font-weight: bold;
padding: 8px 16px;
cursor: pointer;
border-radius: 3px;
}
.sheet-wrap {
padding: 24px 0 48px;
}
.sheet {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
background: #fff;
padding: 14mm 14mm 16mm;
box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.title {
text-align: center;
margin: 14px 0 4px;
}
.title h1 {
margin: 0;
font-size: 14px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.title p {
margin: 4px 0 0;
font-size: 10px;
color: #333;
}
.section {
margin-top: 12px;
}
.section-title {
font-size: 11px;
font-weight: bold;
background: #eef1f4;
border: 1px solid #111;
border-bottom: 0;
padding: 5px 8px;
text-transform: uppercase;
}
table.fields {
width: 100%;
border-collapse: collapse;
font-size: 11px;
}
table.fields th,
table.fields td {
border: 1px solid #111;
padding: 6px 8px;
vertical-align: top;
text-align: left;
}
table.fields th {
width: 28%;
font-weight: normal;
background: #fafbfc;
color: #222;
}
table.fields td.amt {
font-size: 16px;
font-weight: bold;
letter-spacing: 0.02em;
}
.akuan {
font-size: 11px;
line-height: 1.55;
border: 1px solid #111;
padding: 10px 12px;
}
.akuan ol {
margin: 6px 0 0;
padding-left: 18px;
}
.akuan li { margin-bottom: 4px; }
.signs {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
margin-top: 16px;
}
.sign-box {
border: 1px solid #111;
min-height: 150px;
padding: 8px;
font-size: 10px;
}
.sign-box .role {
font-weight: bold;
text-align: center;
text-transform: uppercase;
border-bottom: 1px solid #ccc;
padding-bottom: 4px;
margin-bottom: 8px;
}
.sign-line {
margin-top: 62px;
border-top: 1px solid #111;
padding-top: 6px;
}
.sign-line p { margin: 2px 0; }
@page {
size: A4;
margin: 10mm;
}
@media print {
body { background: #fff; }
.toolbar { display: none !important; }
.sheet-wrap { padding: 0; }
.sheet {
width: auto;
min-height: 0;
margin: 0;
padding: 0;
box-shadow: none;
}
}
</style>
</head>
<body>
@php
// Dummy data — replace later with real gadai / customer / bank values
$cawangan = 'KOTA BHARU 2';
$kodcaw = 'KB2';
$alamat1 = 'Lot 123, Jalan Sultan Yahya Petra';
$alamat2 = '15200 Kota Bharu, Kelantan';
$notel = '09-123 4567';
$norujukan = 'KB2-260903-0001';
$tarikh = '03/09/2026';
$teller = 'SITI AMINAH BINTI ALI';
$nama = 'AHMAD BIN ABDULLAH';
$nokp = '900101-03-1234';
$nopelanggan = 'KB2001234';
$telefon = '012-3456789';
$pinjaman = '15,000.00';
$bank = 'Malayan Banking Berhad (MAYBANK)';
$noakaun = '123456789012';
$nama_akaun = 'AHMAD BIN ABDULLAH';
@endphp
<div class="toolbar">
<div>
<b>DUMMY FORM</b>
<span class="hint"> reka bentuk borang pengesahan pembiayaan online. Data ini contoh sahaja.</span>
</div>
<button type="button" onclick="window.print()">Cetak / Pratinjau</button>
</div>
<div class="sheet-wrap">
<div class="sheet">
<x-print.header
:cawangan="$cawangan"
:kodcaw="$kodcaw"
:alamat1="$alamat1"
:alamat2="$alamat2"
:notel="$notel"
:tarikh="$tarikh"
:show-dummy-badge="true"
/>
<div class="title">
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Online (Akaun Bank)</h1>
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
</div>
<div class="section">
<div class="section-title">A. Maklumat Pelanggan</div>
<table class="fields">
<tr>
<th>Nama Pelanggan</th>
<td colspan="3">{{ $nama }}</td>
</tr>
<tr>
<th>No. MyKad / Passport</th>
<td>{{ $nokp }}</td>
<th style="width:22%">No. Pelanggan</th>
<td>{{ $nopelanggan }}</td>
</tr>
<tr>
<th>No. Telefon</th>
<td>{{ $telefon }}</td>
<th>Cawangan</th>
<td>{{ $cawangan }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">B. Maklumat Pembiayaan</div>
<table class="fields">
<tr>
<th>No. Surat Akuan Gadai</th>
<td>{{ $norujukan }}</td>
</tr>
<tr>
<th>Amaun Pembiayaan</th>
<td class="amt">RM {{ $pinjaman }}</td>
</tr>
<tr>
<th>Cara Terima Pembiayaan</th>
<td>Online (kredit ke akaun bank) bukan tunai</td>
</tr>
<tr>
<th>Teller</th>
<td>{{ $teller }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">C. Maklumat Akaun Bank Penerima</div>
<table class="fields">
<tr>
<th>Nama Bank</th>
<td>{{ $bank }}</td>
</tr>
<tr>
<th>No. Akaun</th>
<td>{{ $noakaun }}</td>
</tr>
<tr>
<th>Nama Pemegang Akaun</th>
<td>{{ $nama_akaun }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">D. Akuan Pelanggan</div>
<div class="akuan">
Saya, <b>{{ $nama }}</b> (No. KP: <b>{{ $nokp }}</b>), dengan ini mengesahkan bahawa:
<ol>
<li>Maklumat akaun bank di Bahagian C adalah benar, tepat, dan milik saya sendiri.</li>
<li>Saya memohon supaya amaun pembiayaan gadai sebanyak <b>RM {{ $pinjaman }}</b> dikreditkan ke akaun tersebut dan <b>bukan</b> diterima secara tunai.</li>
<li>Saya faham kredit ke akaun tertakluk kepada semakan Pengurus Cawangan dan proses pembayaran pihak Koperasi.</li>
<li>Saya bertanggungjawab sepenuhnya jika maklumat akaun tidak tepat, dan tidak akan menuntut ganti rugi atas kelewatan atau ralat yang berpunca daripadanya.</li>
</ol>
</div>
</div>
<div class="signs">
<div class="sign-box">
<div class="role">Tandatangan Pelanggan</div>
<div class="sign-line">
<p>Nama: {{ $nama }}</p>
<p>No. KP: {{ $nokp }}</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Tandatangan Teller</div>
<div class="sign-line">
<p>Nama: {{ $teller }}</p>
<p>Cop / Paraf:</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Pengurus Cawangan</div>
<div class="sign-line">
<p>Nama:</p>
<p>Cop cawangan:</p>
<p>Tarikh:</p>
</div>
</div>
</div>
<x-print.footer>
<b>Nota:</b>
<p>1. Borang ini dicetak semasa pelanggan memilih cara terima pembiayaan secara Online.</p>
<p>2. Pembiayaan akan dikreditkan ke akaun selepas semakan PC. Pelanggan tidak menerima wang tunai di kaunter.</p>
<p>3. Sila pastikan nama pemegang akaun sepadan dengan nama pelanggan pada MyKad.</p>
</x-print.footer>
</div>
</div>
</body>
</html>
@@ -290,6 +290,7 @@
<input type="text" name="nokp" id="nokp" value="{{ !empty($customer_info['kpbaru']) ? $customer_info['kpbaru'] : ($customer_info['kplama'] ?? '') }}" hidden>
<a href="{{ route('gadai.batal',['norujukan'=>$norujukan]) }}" class="float-right btn btn-danger mr-2">Batal</a>
<input type="submit" name="terima_gadai" id="terima_gadai" class="float-right btn btn-primary mr-2" value="Terima">
<button type="button" id="cetak_borang_online" class="float-right btn btn-info mr-2" style="display:none;">Cetak Borang</button>
</div>
</div>
</form>
@@ -1271,6 +1272,7 @@
} else {
$('#cara_terima_section').hide();
$('#bank_online_section').hide();
$('#cetak_borang_online').hide();
$('#cara_terima_tunai').prop('checked', true);
}
}
@@ -1278,11 +1280,13 @@
function toggleBankOnlineSection() {
if ($('input[name="cara_terima"]:checked').val() === 'ONLINE') {
$('#bank_online_section').show();
$('#cetak_borang_online').show();
var nama = $('#gadai_kodbank option:selected').data('nama') || '';
$('#gadai_nama_bank').val(nama);
refreshModalOnlineStatus();
} else {
$('#bank_online_section').hide();
$('#cetak_borang_online').hide();
}
}
@@ -1294,6 +1298,40 @@
$('#gadai_nama_bank').val($('#gadai_kodbank option:selected').data('nama') || '');
});
$(document).on('click', '#cetak_borang_online', function () {
var kodbank = $('#gadai_kodbank').val();
var noakaun = ($('#gadai_noakaun').val() || '').trim();
var namaAkaun = ($('#gadai_nama_akaun').val() || '').trim();
var namaBank = $('#gadai_kodbank option:selected').data('nama') || $('#gadai_nama_bank').val() || '';
var pinjaman = String($('#pinjaman').val() || '').replace(/,/g, '');
if (!kodbank || !noakaun) {
Swal.fire({
icon: 'warning',
title: 'Maklumat bank tidak lengkap',
text: 'Sila lengkapkan bank dan no. akaun sebelum cetak borang. Anda boleh betulkan dan cetak semula tanpa tekan Terima.'
});
return;
}
var form = $('<form>', {
method: 'POST',
action: '{{ route("gadai.print.borang.online.preview") }}',
target: '_blank'
});
form.append($('<input>', { type: 'hidden', name: '_token', value: '{{ csrf_token() }}' }));
form.append($('<input>', { type: 'hidden', name: 'norujukan', value: $('#norujukan_gadai').val() || $('#norujukan').val() || '' }));
form.append($('<input>', { type: 'hidden', name: 'nokp', value: $('#nokp').val() || '' }));
form.append($('<input>', { type: 'hidden', name: 'nopelanggan', value: $('#nopelanggan').val() || '' }));
form.append($('<input>', { type: 'hidden', name: 'nama_pelanggan', value: $('input[name="nama_pelanggan"]').val() || '' }));
form.append($('<input>', { type: 'hidden', name: 'pinjaman', value: pinjaman }));
form.append($('<input>', { type: 'hidden', name: 'kodbank', value: kodbank }));
form.append($('<input>', { type: 'hidden', name: 'nama_bank', value: namaBank }));
form.append($('<input>', { type: 'hidden', name: 'noakaun', value: noakaun }));
form.append($('<input>', { type: 'hidden', name: 'nama_akaun', value: namaAkaun }));
form.appendTo('body').trigger('submit').remove();
});
async function getModalOnline() {
let kodcaw = $('#kodcaw').val();
let apiUrl = api_url + '/api/modal-online/' + kodcaw;
@@ -45,6 +45,11 @@
<div class="card-header d-flex justify-content-between align-items-center flex-wrap">
<h5 class="mb-0">Senarai Dalam Batch</h5>
<div class="mt-2 mt-md-0">
<a href="{{ route('pembiayaan.online.operasi.batch.print', ['kodcaw' => $kodcaw, 'batchId' => $batch['id']]) }}"
class="btn btn-outline-dark btn-sm"
target="_blank">
Cetak Borang
</a>
<a href="{{ route('pembiayaan.online.operasi') }}" class="btn btn-secondary btn-sm">Kembali</a>
@if($pendingCount > 0)
<form method="post"
@@ -0,0 +1,336 @@
<!DOCTYPE html>
<html lang="ms">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Borang Kelulusan Batch {{ $batchNo }}</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
window.print();
});
</script>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #e8eaed;
font-family: Arial, Helvetica, sans-serif;
color: #111;
}
.toolbar {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 16px;
background: #1f3a5f;
color: #fff;
font-size: 13px;
}
.toolbar button {
border: 0;
background: #fff;
color: #1f3a5f;
font-weight: bold;
padding: 8px 16px;
cursor: pointer;
border-radius: 3px;
}
.sheet-wrap {
padding: 24px 0 48px;
}
.sheet {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
background: #fff;
padding: 14mm 12mm 16mm;
box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.title {
text-align: center;
margin: 14px 0 4px;
}
.title h1 {
margin: 0;
font-size: 14px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.title p {
margin: 4px 0 0;
font-size: 10px;
color: #333;
}
.section {
margin-top: 12px;
}
.section-title {
font-size: 11px;
font-weight: bold;
background: #eef1f4;
border: 1px solid #111;
border-bottom: 0;
padding: 5px 8px;
text-transform: uppercase;
}
table.fields {
width: 100%;
border-collapse: collapse;
font-size: 11px;
}
table.fields th,
table.fields td {
border: 1px solid #111;
padding: 6px 8px;
vertical-align: top;
text-align: left;
}
table.fields th {
width: 22%;
font-weight: normal;
background: #fafbfc;
color: #222;
}
table.fields td.amt {
font-size: 14px;
font-weight: bold;
letter-spacing: 0.02em;
}
table.lines {
width: 100%;
border-collapse: collapse;
font-size: 9.5px;
}
table.lines th,
table.lines td {
border: 1px solid #111;
padding: 4px 5px;
vertical-align: top;
}
table.lines thead th {
background: #eef1f4;
font-weight: bold;
text-align: center;
text-transform: uppercase;
font-size: 8.5px;
letter-spacing: 0.02em;
}
table.lines td.num { text-align: center; }
table.lines td.amt { text-align: right; white-space: nowrap; }
table.lines tfoot td {
font-weight: bold;
background: #fafbfc;
}
.akuan {
font-size: 11px;
line-height: 1.55;
border: 1px solid #111;
padding: 10px 12px;
}
.akuan ol {
margin: 6px 0 0;
padding-left: 18px;
}
.akuan li { margin-bottom: 4px; }
.signs {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 16px;
}
.sign-box {
border: 1px solid #111;
min-height: 160px;
padding: 8px 10px;
font-size: 10px;
}
.sign-box .role {
font-weight: bold;
text-align: center;
text-transform: uppercase;
border-bottom: 1px solid #ccc;
padding-bottom: 4px;
margin-bottom: 8px;
}
.sign-line {
margin-top: 72px;
border-top: 1px solid #111;
padding-top: 6px;
}
.sign-line p { margin: 2px 0; }
@page {
size: A4;
margin: 10mm;
}
@media print {
body { background: #fff; }
.toolbar { display: none !important; }
.sheet-wrap { padding: 0; }
.sheet {
width: auto;
min-height: 0;
margin: 0;
padding: 0;
box-shadow: none;
}
table.lines thead { display: table-header-group; }
table.lines tfoot { display: table-footer-group; }
}
</style>
</head>
<body>
<div class="toolbar">
<div><b>Borang Kelulusan Batch Pembiayaan Online</b></div>
<button type="button" onclick="window.print()">Cetak</button>
</div>
<div class="sheet-wrap">
<div class="sheet">
<x-print.header
:cawangan="$cawangan"
:kodcaw="$kodcaw"
:alamat1="$alamat1"
:alamat2="$alamat2"
:notel="$notel"
:tarikh="$tarikh"
:norujukan="$batchNo"
rujukan-label="No. Batch"
/>
<div class="title">
<h1>Borang Kelulusan Pembiayaan Online<br>Senarai Batch Pembayaran</h1>
<p>Untuk semakan Operasi dan kelulusan Pengurus Besar. Bukan untuk tandatangan pelanggan.</p>
</div>
<div class="section">
<div class="section-title">A. Maklumat Batch</div>
<table class="fields">
<tr>
<th>No. Batch</th>
<td>{{ $batchNo }}</td>
<th>Cawangan</th>
<td>{{ $kodcaw }} {{ $cawangan }}</td>
</tr>
<tr>
<th>Tarikh / Slot</th>
<td>{{ $tarikh }} &nbsp;·&nbsp; {{ $slot }}</td>
<th>Status Batch</th>
<td>{{ $status }}</td>
</tr>
<tr>
<th>Dihantar Oleh (PC)</th>
<td>{{ $dihantarOleh }}</td>
<th>Dihantar Pada</th>
<td>{{ $dihantarPada }}</td>
</tr>
<tr>
<th>Bilangan Rekod</th>
<td>{{ count($lines) }}</td>
<th>Jumlah Keseluruhan</th>
<td class="amt">RM {{ number_format((float) $jumlah, 2) }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">B. Senarai Penerima Dalam Batch</div>
<table class="lines">
<thead>
<tr>
<th style="width:4%">Bil</th>
<th style="width:14%">No. SAG</th>
<th>Pelanggan</th>
<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 style="width:12%">Pinjaman (RM)</th>
</tr>
</thead>
<tbody>
@forelse($lines as $i => $line)
<tr>
<td class="num">{{ $i + 1 }}</td>
<td class="num">{{ $line['norujukan'] ?? '-' }}</td>
<td>{{ $line['nama_pelanggan'] ?? '-' }}</td>
<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 class="amt">{{ number_format((float) ($line['pinjaman'] ?? 0), 2) }}</td>
</tr>
@empty
<tr>
<td colspan="8" class="num">Tiada rekod dalam batch.</td>
</tr>
@endforelse
</tbody>
<tfoot>
<tr>
<td colspan="7" style="text-align:right">JUMLAH</td>
<td class="amt">{{ number_format((float) $jumlah, 2) }}</td>
</tr>
</tfoot>
</table>
</div>
<div class="section">
<div class="section-title">C. Pengesahan Operasi</div>
<div class="akuan">
Dengan ini disahkan bahawa senarai di Bahagian B telah disemak dan amaun pembiayaan
sebanyak <b>RM {{ number_format((float) $jumlah, 2) }}</b> ({{ count($lines) }} rekod)
bagi batch <b>{{ $batchNo }}</b> cawangan <b>{{ $cawangan }}</b> adalah lengkap
untuk proses pembayaran ke akaun bank pelanggan.
<ol>
<li>Maklumat SAG, nama, no. KP, bank dan no. akaun telah disemak terhadap rekod sistem.</li>
<li>Pembayaran akan dikreditkan ke akaun penerima seperti senarai, bukan tunai di kaunter.</li>
<li>Sebarang ralat akaun yang dikesan selepas kelulusan hendaklah dilaporkan serta-merta.</li>
</ol>
</div>
</div>
<div class="signs">
<div class="sign-box">
<div class="role">Tandatangan Operasi</div>
<div class="sign-line">
<p>Nama: {{ $opsBy }}</p>
<p>Jawatan: Operasi</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Pengurus Besar</div>
<div class="sign-line">
<p>Nama:</p>
<p>Cop / Paraf:</p>
<p>Tarikh:</p>
</div>
</div>
</div>
<x-print.footer :show-copies="false">
<b>Nota:</b>
<p>1. Borang ini dicetak dari skrin Operasi Pembiayaan Online (Batch) untuk kelulusan pembayaran.</p>
<p>2. Hanya dua tandatangan diperlukan: Operasi dan Pengurus Besar.</p>
<p>3. Simpan salinan bersama bukti pindahan bank selepas status PAID.</p>
</x-print.footer>
</div>
</div>
</body>
</html>
@@ -0,0 +1,302 @@
<!DOCTYPE html>
<html lang="ms">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Borang Pengesahan Online {{ $norujukan }}</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
window.print();
});
</script>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
background: #e8eaed;
font-family: Arial, Helvetica, sans-serif;
color: #111;
}
.toolbar {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 16px;
background: #1f3a5f;
color: #fff;
font-size: 13px;
}
.toolbar button {
border: 0;
background: #fff;
color: #1f3a5f;
font-weight: bold;
padding: 8px 16px;
cursor: pointer;
border-radius: 3px;
}
.sheet-wrap {
padding: 24px 0 48px;
}
.sheet {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
background: #fff;
padding: 14mm 14mm 16mm;
box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.title {
text-align: center;
margin: 14px 0 4px;
}
.title h1 {
margin: 0;
font-size: 14px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.title p {
margin: 4px 0 0;
font-size: 10px;
color: #333;
}
.section {
margin-top: 12px;
}
.section-title {
font-size: 11px;
font-weight: bold;
background: #eef1f4;
border: 1px solid #111;
border-bottom: 0;
padding: 5px 8px;
text-transform: uppercase;
}
table.fields {
width: 100%;
border-collapse: collapse;
font-size: 11px;
}
table.fields th,
table.fields td {
border: 1px solid #111;
padding: 6px 8px;
vertical-align: top;
text-align: left;
}
table.fields th {
width: 28%;
font-weight: normal;
background: #fafbfc;
color: #222;
}
table.fields td.amt {
font-size: 16px;
font-weight: bold;
letter-spacing: 0.02em;
}
.akuan {
font-size: 11px;
line-height: 1.55;
border: 1px solid #111;
padding: 10px 12px;
}
.akuan ol {
margin: 6px 0 0;
padding-left: 18px;
}
.akuan li { margin-bottom: 4px; }
.signs {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
margin-top: 16px;
}
.sign-box {
border: 1px solid #111;
min-height: 150px;
padding: 8px;
font-size: 10px;
}
.sign-box .role {
font-weight: bold;
text-align: center;
text-transform: uppercase;
border-bottom: 1px solid #ccc;
padding-bottom: 4px;
margin-bottom: 8px;
}
.sign-line {
margin-top: 62px;
border-top: 1px solid #111;
padding-top: 6px;
}
.sign-line p { margin: 2px 0; }
@page {
size: A4;
margin: 10mm;
}
@media print {
body { background: #fff; }
.toolbar { display: none !important; }
.sheet-wrap { padding: 0; }
.sheet {
width: auto;
min-height: 0;
margin: 0;
padding: 0;
box-shadow: none;
}
}
</style>
</head>
<body>
<div class="toolbar">
<div><b>Borang Pengesahan Pembiayaan Online</b></div>
<button type="button" onclick="window.print()">Cetak</button>
</div>
<div class="sheet-wrap">
<div class="sheet">
<x-print.header
:cawangan="$cawangan"
:kodcaw="$kodcaw"
:alamat1="$alamat1"
:alamat2="$alamat2"
:notel="$notel"
:tarikh="$tarikh"
/>
<div class="title">
<h1>Borang Pengesahan Penerimaan Pembiayaan<br>Secara Online (Akaun Bank)</h1>
<p>Untuk diisi dan ditandatangani oleh pelanggan semasa transaksi gadai.</p>
</div>
<div class="section">
<div class="section-title">A. Maklumat Pelanggan</div>
<table class="fields">
<tr>
<th>Nama Pelanggan</th>
<td colspan="3">{{ $nama }}</td>
</tr>
<tr>
<th>No. MyKad / Passport</th>
<td>{{ $nokp }}</td>
<th style="width:22%">No. Pelanggan</th>
<td>{{ $nopelanggan }}</td>
</tr>
<tr>
<th>No. Telefon</th>
<td>{{ $telefon }}</td>
<th>Cawangan</th>
<td>{{ $cawangan }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">B. Maklumat Pembiayaan</div>
<table class="fields">
<tr>
<th>No. Surat Akuan Gadai</th>
<td>{{ $norujukan }}</td>
</tr>
<tr>
<th>Amaun Pembiayaan</th>
<td class="amt">RM {{ $pinjaman }}</td>
</tr>
<tr>
<th>Cara Terima Pembiayaan</th>
<td>Online (kredit ke akaun bank) bukan tunai</td>
</tr>
<tr>
<th>Teller</th>
<td>{{ $teller }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">C. Maklumat Akaun Bank Penerima</div>
<table class="fields">
<tr>
<th>Nama Bank</th>
<td>{{ $bank }}</td>
</tr>
<tr>
<th>No. Akaun</th>
<td>{{ $noakaun }}</td>
</tr>
<tr>
<th>Nama Pemegang Akaun</th>
<td>{{ $nama_akaun }}</td>
</tr>
</table>
</div>
<div class="section">
<div class="section-title">D. Akuan Pelanggan</div>
<div class="akuan">
Saya, <b>{{ $nama }}</b> (No. KP: <b>{{ $nokp }}</b>), dengan ini mengesahkan bahawa:
<ol>
<li>Maklumat akaun bank di Bahagian C adalah benar, tepat, dan milik saya sendiri.</li>
<li>Saya memohon supaya amaun pembiayaan gadai sebanyak <b>RM {{ $pinjaman }}</b> dikreditkan ke akaun tersebut dan <b>bukan</b> diterima secara tunai.</li>
<li>Saya faham kredit ke akaun tertakluk kepada semakan Pengurus Cawangan dan proses pembayaran pihak Koperasi.</li>
<li>Saya bertanggungjawab sepenuhnya jika maklumat akaun tidak tepat, dan tidak akan menuntut ganti rugi atas kelewatan atau ralat yang berpunca daripadanya.</li>
</ol>
</div>
</div>
<div class="signs">
<div class="sign-box">
<div class="role">Tandatangan Pelanggan</div>
<div class="sign-line">
<p>Nama: {{ $nama }}</p>
<p>No. KP: {{ $nokp }}</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Tandatangan Teller</div>
<div class="sign-line">
<p>Nama: {{ $teller }}</p>
<p>Cop / Paraf:</p>
<p>Tarikh: {{ $tarikh }}</p>
</div>
</div>
<div class="sign-box">
<div class="role">Pengurus Cawangan</div>
<div class="sign-line">
<p>Nama:</p>
<p>Cop cawangan:</p>
<p>Tarikh:</p>
</div>
</div>
</div>
<x-print.footer>
<b>Nota:</b>
<p>1. Borang ini dicetak semasa pelanggan memilih cara terima pembiayaan secara Online.</p>
<p>2. Pembiayaan akan dikreditkan ke akaun selepas semakan PC. Pelanggan tidak menerima wang tunai di kaunter.</p>
<p>3. Sila pastikan nama pemegang akaun sepadan dengan nama pelanggan pada MyKad.</p>
</x-print.footer>
</div>
</div>
</body>
</html>
+12
View File
@@ -19,6 +19,15 @@ Route::get('/health', function () {
return response()->json(['status' => 'ok']);
});
// Dummy print form — no auth, for layout design only
Route::get('/dummy/borang-pengesahan-online', function () {
return view('dummy.borang_pengesahan_online');
});
Route::get('/dummy/borang-batch-pembiayaan-online', function () {
return view('dummy.borang_batch_pembiayaan_online');
});
Route::get('/',['as'=>'login','uses'=>'HomeController@index']);
Route::get('/testtry',function(ImbangdugaServices $imbangduga){
@@ -113,6 +122,8 @@ Route::post('/profile/edit/store',['as'=>'profile.editstore','uses'=>'UserContro
Route::get('/customer/search',['as'=>'customer.search','uses'=>'CustomersController@search'])->middleware('auth','teller');
Route::post('/customer/store',['as'=>'customer.store','uses'=>'CustomersController@store'])->middleware('auth','teller');
Route::post('/gadai/store',['as'=>'gadai.store','uses'=>'GadaianController@store'])->middleware('auth','teller');
Route::get('/gadai/borang-pengesahan-online/{norujukan}',['as'=>'gadai.print.borang.online','uses'=>'GadaianController@printBorangPengesahanOnline'])->middleware('auth','teller');
Route::post('/gadai/borang-pengesahan-online/preview',['as'=>'gadai.print.borang.online.preview','uses'=>'GadaianController@previewBorangPengesahanOnline'])->middleware('auth','teller');
Route::get('/gadai/batal',['as'=>'gadai.batal','uses'=>'GadaianController@batal'])->middleware('auth','teller');
Route::get('/customer/otp',['as'=>'customer.otp','uses'=>'CustomersController@getOTP'])->middleware('auth','teller');
Route::get('/getwakil',['as'=>'wakil.search','uses'=>'PenebusanController@getWakil'])->middleware('auth','teller');
@@ -194,6 +205,7 @@ Route::get('/pembiayaan-online/operasi/eod',['as'=>'pembiayaan.online.operasi.eo
Route::post('/pembiayaan-online/operasi/eod/close-all',['as'=>'pembiayaan.online.operasi.eod.closeall','uses'=>'PembiayaanOnlineController@operasiCloseAllModal'])->middleware('auth','operasi');
Route::post('/pembiayaan-online/operasi/eod/{kodcaw}/close',['as'=>'pembiayaan.online.operasi.eod.close','uses'=>'PembiayaanOnlineController@operasiCloseModal'])->middleware('auth','operasi');
Route::get('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}',['as'=>'pembiayaan.online.operasi.batch','uses'=>'PembiayaanOnlineController@operasiShowBatch'])->middleware('auth','operasi');
Route::get('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/print',['as'=>'pembiayaan.online.operasi.batch.print','uses'=>'PembiayaanOnlineController@operasiPrintBatch'])->middleware('auth','operasi');
Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/approve',['as'=>'pembiayaan.online.operasi.approve','uses'=>'PembiayaanOnlineController@operasiApproveLine'])->middleware('auth','operasi');
Route::post('/pembiayaan-online/operasi/{kodcaw}/lines/{id}/reject',['as'=>'pembiayaan.online.operasi.reject','uses'=>'PembiayaanOnlineController@operasiRejectLine'])->middleware('auth','operasi');
Route::post('/pembiayaan-online/operasi/{kodcaw}/batches/{batchId}/approve',['as'=>'pembiayaan.online.operasi.approve.batch','uses'=>'PembiayaanOnlineController@operasiApproveBatch'])->middleware('auth','operasi');