Penambahan Stiker Harian

This commit is contained in:
pand03
2026-02-11 07:57:15 +07:00
parent 7401144113
commit 23114b1cfb
15 changed files with 1180 additions and 49 deletions

View File

@@ -1,10 +1,31 @@
@extends('layouts.master')
@section('styles')
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.8/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{{ asset('vendors/select2/select2.min.css') }}">
<style>
.select2-container .select2-selection--single {
height: 48px;
}
.select2-container--default
.select2-selection--single
.select2-selection__rendered {
line-height: 38px;
}
.select2-container--default
.select2-selection--single
.select2-selection__arrow {
height: 38px;
}
.table th {
text-align: center;
}
.table td {
/* text-align: right; */
}
</style>
@endsection
@@ -16,39 +37,84 @@
<div class="row">
<div class="col-md-12 grid-margin stretch-card">
<div class="card">
<div class="card-body" id="cetak">
<div class="card-body">
<h4 class="card-title">Laporan Stiker Harian</h4>
<form id="formTanggal">
<div class="form-group">
<div class="row">
<div class="col-sm-3">
<label for="tanggalMulai">Tanggal pencarian</label>
<div class="col-sm-2">
<div class="d-flex gap-2">
<input type="date" class="form-control" id="tanggalMulai" name="tanggal_mulai">
</div>
<div class="mt-3">
<input type="text" class="form-control" id="cari_data" name="cariData" placeholder="Cari berdasarkan Nama">
</div>
</div>
<div class="col-sm-3">
<input type="date" class="form-control" id="tanggalCari" name="tanggal_mulai" required>
<div class="col-sm-2">
<div class="d-flex gap-2">
<input type="date" class="form-control" id="tanggalSelesai" name="tanggal_selesai">
</div>
<div class="mt-3">
<input type="text" class="form-control" id="cari_nopol" name="cariData" placeholder="Cari berdasarkan No. Polisi">
</div>
</div>
<div class="col-sm-2">
<div class="d-flex gap-2">
<select id="jenisLangganan" class="form-control js-example-basic-multiple" data-placeholder="Jenis Langganan : (SEMUA)" multiple="multiple">
@foreach ($filterSelect['jenisLangganan'] as $jenisLangganan )
<option value="{{ $jenisLangganan->id }}">{{ $jenisLangganan->nama }}</option>
@endforeach
</select>
</div>
<div class="mt-3">
<select id="jenisStiker" class="form-control js-example-basic-multiple" data-placeholder="Jenis Stiker : (SEMUA)" multiple="multiple">
@foreach ($filterSelect['jenisStiker'] as $jStiker )
<option value="{{ $jStiker->kode }}">{{ $jStiker->nama }}</option>
@endforeach
</select>
</div>
</div>
<div class="col-sm-1">
<div class="form-group">
<button type="button" id="btnProses" class="btn btn-outline-secondary btn-lg btn-block">Proses</button>
</div>
</div>
<div class="col-sm-1">
</div>
<div class="col-sm-2">
<div class="form-group">
<p>Jumlah pendapatan : </p> <h3 id="pendapatan"></h3>
</div>
</div>
<div class="col-sm-1">
<button type="button" class="btn btn-info btn-icon-text btn-export-pdf">
Print
<i class="mdi mdi-printer btn-icon-append"></i>
</button>
</div>
</div>
</div>
</form>
<div class="table-bordered">
<table class="table">
<thead>
<tr>
<th>No.</th>
<th>No. Transaksi</th>
<th>Tanggal</th>
<th>Nama</th>
<th>Alamat</th>
<th>Telp</th>
<th>Jenis Trans</th>
<th>No. Polisi</th>
<th>Jenis Kend</th>
<th>Petugas</th>
</tr>
</thead>
<tbody>
</tbody>
<div class="table-bordered" id="cetak">
<table id="table-stiker" class="table table-striped table-bordered">
<thead>
<tr>
<th width="3%">No.</th>
<th width="10%">No. Transaksi</th>
<th>Nama</th>
<th>No. Telp</th>
<th>Alamat / Email</th>
<th width="15%">Periode</th>
<th>No. Polisi<br>Terdaftar</th>
<th>Jenis Trans</th>
<th>Harga</th>
<th>Tanggal</th>
{{-- <th>No. Polisi</th> --}}
<th>Petugas</th>
</tr>
</thead>
<tbody id="tbodyResult">
</tbody>
</table>
</div>
</div>
@@ -59,4 +125,426 @@
</div>
</div>
</div>
@endsection
@section('javascript')
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdn.datatables.net/1.13.8/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.31/jspdf.plugin.autotable.min.js"></script>
<script src="{{ asset('vendors/select2/select2.min.js') }}"></script>
<script src="{{ asset('js/select2.js') }}"></script>
<script>
$(document).ready(function () {
let location = @json($locationSettings);
console.log(location.namaperusahaan);
let awal = '';
let akhir = '';
let pendapatan = 0;
let pdfData = [];
$('#btnProses').on('click', function () {
const jenisLangganan = $('#jenisLangganan').val();
const jenisStiker = $('#jenisStiker').val();
const nama = $('#cari_data').val();
const nopol = $('#cari_nopol').val();
awal = $('#tanggalMulai').val();
akhir = $('#tanggalSelesai').val();
// if (!jenisLangganan || jenisLangganan.length === 0) {
// alert('Pilih minimal 1 jenis langganan');
// return;
// }
if (!awal || !akhir) {
alert('Periode harus diisi');
return;
}
const btn = $(this);
btn.prop('disabled', true).text('Memproses...');
$('#alertSuccess').addClass('d-none');
$.ajax({
url: "{{ route('stikerData') }}",
type: "GET",
data: {
jenis_langganan: jenisLangganan,
jenis_stiker: jenisStiker,
tanggalAwal: awal,
tanggalAkhir: akhir,
name: nama,
no_pol: nopol,
_token: "{{ csrf_token() }}"
},
success: function(response) {
pdfData = response.data;
console.log(response);
const tbody = $('#tbodyResult');
tbody.empty();
// $.each(response.data, function (i, row) {
// pendapatan += parseInt(row.harga || 0, 10);
// tbody.append(`
// <tr>
// <td class="text-center">${i + 1}</td>
// <td class="text-center">${row.notrans ?? '-'}</td>
// <td class="text-left">${row.nama ?? '-'}</td>
// <td class="text-left">${row.telepon ?? '-'}</td>
// <td class="text-left">${row.alamat ?? '-'}</td>
// <td class="text-center">${row.awal ?? '-'} - ${row.akhir ?? '-'}</td>
// <td class="text-center">${row.nopol ?? '-'}</td>
// <td>${row.jenis_langganan ?? '-'}</td>
// <td>${row.harga ?? ''}</td>
// <td>${row.tgl_edited ?? ''}</td>
// <td class="text-end">${row.operator ?? ''}</td>
// </tr>
// `);
// });
// initDataTable();
// 🔥 sortable aktif
if (!response.success) return;
// const tbody = $('#tbodyResult');
// tbody.empty(); // 🔥 hapus isi lama
if (response.data.length === 0) {
tbody.append(`
<tr>
<td colspan="11" class="text-center text-danger text-muted">
Tidak ada data
</td>
</tr>
`);
return;
}
$.each(response.data, function (i, row) {
pendapatan += parseInt(row.harga || 0, 10);
awalDate = row.awal.toString('YYYY-MM-DD');
tbody.append(`
<tr>
<td class="text-center">${i + 1}</td>
<td class="text-center">${row.notrans ?? '-'}</td>
<td class="text-left">${row.nama ?? '-'}</td>
<td class="text-center">${row.telp ?? '-'}</td>
<td class="text-center">${row.alamat ?? '-'}</td>
<td>
${row.awal.split(' ')[0] ?? ''} <br>
<small class="text-muted">s/d ${row.akhir.split(' ')[0] ?? ''}</small>
</td>
<td class="text-center">${row.nopol ?? '-'}</td>
<td>${row.jenis_member ?? '-'}</td>
<td>${row.harga ?? ''}</td>
<td>${row.tgl_edited ?? ''}</td>
<td class="text-end">${row.operator ?? ''}</td>
</tr>
`);
// <td>${row.jenis_langganan ?? '-'}</td>
});
$('#pendapatan').text('Rp. ' + rupiah(pendapatan));
btn.prop('disabled', false).text('Proses');
},
error: function (xhr) {
console.log(xhr.responseText);
}
});
});
function rupiah(angka) {
return new Intl.NumberFormat('id-ID').format(angka || 0);
}
// let table;
// function initDataTable() {
// if ($.fn.DataTable.isDataTable('#table-stiker')) {
// table.destroy(); // reset kalau reload data
// }
// table = $('#table-stiker').DataTable({
// order: [[1, 'desc']], // default sort No Transaksi
// pageLength: 10,
// lengthChange: true,
// searching: false,
// info: true,
// });
// }
$('.btn-export-pdf').on('click', function () {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
const pageWidth = doc.internal.pageSize.getWidth();
const pageHeight = doc.internal.pageSize.getHeight();
const marginLeft = 10;
const marginRight = 10;
const marginTop = 20;
const marginBottom = 20;
// =========================
// HEADER FUNCTION
// =========================
const drawHeader = () => {
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.text('LAPORAN STIKER HARIAN', pageWidth / 2, 15, { align: 'center' });
doc.setFontSize(10);
doc.setFont('helvetica', 'normal');
doc.text('PT PARKIR MAJU JAYA', pageWidth / 2, 22, { align: 'center' });
doc.setFontSize(9);
doc.text(`Periode : ${awal} s/d ${akhir}`, marginLeft, 32);
doc.text(
`Dicetak : ${new Date().toLocaleDateString('id-ID')}`,
pageWidth - marginRight,
32,
{ align: 'right' }
);
doc.text(`Jumlah Pendapatan : ${rupiah(pendapatan)}`, marginLeft, 38);
// garis pemisah
doc.line(marginLeft, 40, pageWidth - marginRight, 40);
};
// =========================
// BODY DATA
// =========================
if (pdfData.length === 0) {
alert('Data belum tersedia');
return;
}
const tableBody = pdfData.map((row, i) => ([
i + 1,
row.notrans ?? '-',
row.nama ?? '-',
// row.telepon ?? '-',
row.nopol ?? '-',
row.jenis_langganan ?? '-',
`${row.awal ?? '-'} s/d ${row.akhir ?? '-'}`,
rupiah(row.harga),
// row.operator ?? '-'
]));
// =========================
// AUTOTABLE
// =========================
doc.autoTable({
head: [[
'No',
'No Transaksi',
'Nama',
// 'Telepon',
'No Pol',
'Jenis',
'Periode',
'Harga',
// 'Operator'
]],
body: tableBody,
startY: 45,
margin: {
left: marginLeft,
right: marginRight,
top: marginTop,
bottom: marginBottom
},
styles: {
fontSize: 8,
cellPadding: 2,
valign: 'middle'
},
headStyles: {
fillColor: [220, 220, 220],
textColor: 20,
fontStyle: 'bold',
halign: 'center'
},
columnStyles: {
0: { halign: 'center', cellWidth: 8 },
7: { halign: 'right' }
},
didDrawPage: function (pdfData) {
// drawHeader();
if (pdfData.pageNumber === 1) {
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.text('LAPORAN STIKER HARIAN', pageWidth / 2, 15, { align: 'center' });
doc.setFontSize(10);
doc.setFont('helvetica', 'normal');
doc.text(location.namaperusahaan, pageWidth / 2, 22, { align: 'center' });
doc.setFontSize(9);
doc.text(`Periode : ${awal} s/d ${akhir}`, marginLeft, 32);
doc.text(
`Dicetak : ${new Date().toLocaleDateString('id-ID')}`,
pageWidth - marginRight,
32,
{ align: 'right' }
);
doc.text(`Jumlah Pendapatan : ${rupiah(pendapatan)}`, marginLeft, 38);
doc.line(marginLeft, 40, pageWidth - marginRight, 40);
}
// FOOTER
// const pageCount = doc.internal.getNumberOfPages();
doc.setFontSize(8);
doc.text(
// `Halaman ${doc.internal.getCurrentPageInfo().pageNumber} dari ${pdfData.pageNumber}`,
`Halaman ${pdfData.pageNumber}`,
pageWidth / 2,
pageHeight - 10,
{ align: 'center' }
);
}
});
doc.save('Rekap_Harian.pdf');
});
});
// $('.btn-export-pdf').on('click', async function () {
// const { jsPDF } = window.jspdf;
// const doc = new jsPDF({
// orientation: 'portrait',
// unit: 'mm',
// format: 'a4'
// });
// const element = document.getElementById('cetak');
// const canvas = await html2canvas(element, {
// scale: 2,
// useCORS: true
// });
// const imgData = canvas.toDataURL('image/png');
// const pageWidth = doc.internal.pageSize.getWidth();
// const pageHeight = doc.internal.pageSize.getHeight();
// const marginTop = 20;
// const marginBottom = 20;
// const marginLeft = 10;
// const marginRight = 10;
// const headerHeight = 45; // ⬅️ ruang judul
// const contentHeight = pageHeight - headerHeight - marginBottom;
// const imgWidth = pageWidth - marginLeft - marginRight;
// const imgHeight = (canvas.height * imgWidth) / canvas.width;
// let renderedHight = 0;
// let page = 1;
// let renderedHeight = 0;
// while (renderedHeight < imgHeight) {
// if (page > 1) doc.addPage();
// doc.setFont('helvetica', 'bold');
// doc.setFontSize(14);
// doc.text('LAPORAN STIKER HARIAN', pageWidth / 2, 15, { align: 'center' });
// // SUB JUDUL
// doc.setFontSize(10);
// doc.setFont('helvetica', 'normal');
// doc.text('PT PARKIR MAJU JAYA', pageWidth / 2, 22, { align: 'center' });
// doc.setFontSize(9);
// doc.text(`Periode : ${awal} s/d ${akhir}`, marginLeft, 32);
// doc.text(`Dicetak : ${new Date().toLocaleDateString('id-ID')}`, pageWidth - marginRight, 32, {
// align: 'right'
// });
// doc.setFontSize(9);
// doc.text(`Jumlah Pendapatan : ${pendapatan}`, marginLeft, 38);
// doc.text(`Jumlah Pendapatan : 15`, pageWidth - marginRight, 38, {
// align: 'right'
// });
// doc.addImage(
// imgData,
// 'PNG',
// marginLeft,
// marginTop - renderedHeight,
// imgWidth,
// imgHeight
// );
// renderedHeight += contentHeight;
// page++;
// }
// doc.save('Rekap_Harian.pdf');
// });
// halaman berikutnya
// while (heightLeft > 0) {
// position = heightLeft - imgHeight + marginTop;
// doc.addPage();
// // doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
// doc.addImage(
// imgData,
// 'PNG',
// marginLeft,
// position,
// imgWidth,
// imgHeight
// );
// heightLeft -= (pageHeight - marginTop - marginBottom);
// }
// $('.btn-export-pdf').on('click', async function () {
// // $('.cetak').css('display','block');
// // $('.user').css('display','block');
// const { jsPDF } = window.jspdf;
// const doc = new jsPDF({
// orientation: 'portrait',
// unit: 'mm',
// format: 'a4'});
// // 'l', 'pt'
// // ambil elemen tabel
// const table = document.getElementById('cetak');
// const canvas = await html2canvas(table, { scale: 2 });
// const imgData = canvas.toDataURL('image/png');
// const imgWidth = doc.internal.pageSize.getWidth();
// const imgHeight = (canvas.height * imgWidth) / canvas.width;
// doc.addImage(imgData, 'PNG', 0, 20, imgWidth, imgHeight);
// doc.save(`Rekap Harian.pdf`);
// });
</script>
@endsection