progress label

This commit is contained in:
JokoPrasetio 2025-08-08 16:16:10 +07:00
parent ce77b7b74e
commit b09ad3d424
14 changed files with 284 additions and 66 deletions

View File

@ -44,7 +44,6 @@ class CustomerController extends Controller
$payloadHari = range($tanggal_awal, $tanggal_akhir);
}
}
// Step 1: Ambil menu_id yang sesuai tanggal
$menuIdTanggalValid = [];
if (!empty($payloadHari)) {
@ -54,10 +53,6 @@ class CustomerController extends Controller
->pluck('master_menu_id')
->unique()
->toArray();
// Jika tidak ada menu di tanggal tersebut, return kosong langsung
if (empty($menuIdTanggalValid)) {
return self::emptyMenuResponse($perPage);
}
}
// Step 2: Query menu
$menuQuery = DB::connection('dbOrderGizi')
@ -71,11 +66,21 @@ class CustomerController extends Controller
if (!empty($search)) {
$menuQuery->where('mn.nama_menu', 'ILIKE', '%' . $search . '%');
}
$menuQuery->where(function ($q) use ($menuIdTanggalValid, $payloadHari) {
if (!empty($menuIdTanggalValid)) {
// Jika ada filter tanggal: tampilkan menu sesuai tanggal atau yang someday
$q->whereIn('mn.master_menu_id', $menuIdTanggalValid)
->orWhere('mn.apakah_someday', true);
}else if($payloadHari){
$q->where('mn.apakah_someday', true);
}
// Jika TIDAK ada tanggal, tidak perlu where apapun — biarkan tampil semua menu
});
if (!empty($menuIdTanggalValid)) {
$menuQuery->whereIn('mn.master_menu_id', $menuIdTanggalValid);
}
$paginated = $menuQuery->select(
// }
$menuItems = $menuQuery->select(
'mn.master_menu_id',
'mn.nama_menu',
'mn.foto',
@ -88,9 +93,9 @@ class CustomerController extends Controller
'mn.apakah_someday',
'mn.apakah_menu_siang',
'mn.apakah_menu_sore',
)->paginate($perPage);
)->get();
$menuIds = collect($paginated->items())->pluck('master_menu_id')->toArray();
$menuIds = $menuItems->pluck('master_menu_id')->toArray();
if (empty($menuIds)) {
return self::emptyMenuResponse($perPage);
@ -104,11 +109,17 @@ class CustomerController extends Controller
->select('kmd.master_menu_id', 'kd.kategori_diet_id', 'kd.nama_kategori_diet')
->get()
->groupBy('master_menu_id');
$dmph = DB::connection('dbOrderGizi')
->table('public.detail_menu_paket_harian as dmph')
->whereIn('dmph.master_menu_id', $menuIds)
->select('dmph.master_menu_id', 'dmph.tgl_harian')
// ->orderByRaw("
// CASE
// WHEN tgl_harian >= ? THEN 0
// ELSE 1
// END,
// tgl_harian ASC
// ", [$today])
->get()
->groupBy('master_menu_id');
$kkal = DB::connection('dbOrderGizi')
@ -120,8 +131,7 @@ class CustomerController extends Controller
->groupBy('master_menu_id');
// Step 4: Transform response
$result = collect($paginated->items())->map(function ($menu) use ($klasifikasi, $dmph, $kkal) {
$enriched = $menuItems->map(function ($menu) use ($klasifikasi, $dmph, $kkal) {
return [
'master_menu_id' => $menu->master_menu_id,
'nama' => $menu->nama_menu,
@ -154,17 +164,43 @@ class CustomerController extends Controller
];
});
// Urutkan: someday → tgl_harian terdekat
$sorted = $enriched->sortBy(function ($menu) {
$hariIni = now()->day;
$isSomeday = $menu['apakah_someday'] ? 0 : 1;
if ($menu['apakah_someday']) {
return [0, 0];
}
$tglTerdekat = collect($menu['dmph'])->pluck('tgl_harian')
->map(function ($tgl) use ($hariIni) {
return $tgl >= $hariIni ? $tgl : $tgl + 31;
})
->sort()
->first() ?? 99;
return [$isSomeday, $tglTerdekat];
})->values();
// Paginate manual (setelah sort)
$total = $sorted->count();
$currentPage = request()->get('page', 1);
$offset = ($currentPage - 1) * $perPage;
$pagedData = $sorted->slice($offset, $perPage)->values();
return response()->json([
'status' => true,
'message' => 'Berhasil mendapatkan data',
'data' => [
'data' => $result,
'current_page' => $paginated->currentPage(),
'last_page' => $paginated->lastPage(),
'per_page' => $paginated->perPage(),
'total' => $paginated->total(),
'data' => $pagedData,
'current_page' => (int) $currentPage,
'last_page' => (int) ceil($total / $perPage),
'per_page' => (int) $perPage,
'total' => $total,
]
]);
}
private static function emptyMenuResponse($perPage)
@ -381,6 +417,7 @@ class CustomerController extends Controller
], 200);
return back()->with('success', 'Bukti pembayaran berhasil diunggah.');
} catch (\Throwable $th) {
dd($th);
DB::rollBack();
return response([
'status' => false,

View File

@ -40,9 +40,6 @@ class DashboardController extends Controller
'o.note_dibatalkan',
'od.status_order as detail_status_order')
->get()->groupBy('order_id');
$grouped = $data->map(function($items){
$first = $items->first();
$totalDetail = $items->count();

View File

@ -350,6 +350,14 @@ class PesananController extends Controller
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
public function countPesananPending(){
$count = Order::where('statusenabled', true)->whereIn('status_order', ['Menunggu Konfirmasi Pembayaran', 'Menunggu Konfirmasi Pembayaran Via Billing'])->count();
return response()->json([
'status' => true,
'count' => $count,
]);
}
public function downloadLabel(Request $request){
$items = $request->input('items');

View File

@ -44,7 +44,12 @@ document.addEventListener('DOMContentLoaded', () => {
}else if(currentStep === 1){
const {isValid, errorMessage} =validateCartBeforeSubmit();
if (!isValid) {
alert(errorMessage);
Swal.fire({
title: 'Perhatian!',
text: errorMessage,
icon: 'warning',
confirmButtonText: 'Oke'
})
return
}
let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}');
@ -285,8 +290,21 @@ function renderCartSummary() {
? item.harga_karyawan || 0
: item.harga_public || 0;
const itemTotal = pesananList.reduce((sum, p) => sum + (p.jumlah * harga), 0);
totalKeseluruhan += itemTotal;
console.log(checkout_biodata);
if (checkout_biodata.jenis_customer === "Karyawan RSAB Harapan Kita") {
$('#karyawan').addClass('d-none');
$('#pasien').removeClass('d-none');
} else if (checkout_biodata.jenis_customer === "Keluarga Pasien / Penunggu Pasien") {
$('#karyawan').removeClass('d-none');
$('#pasien').addClass('d-none');
} else {
$('#karyawan').addClass('d-none');
$('#pasien').addClass('d-none');
}
totalKeseluruhan += itemTotal;
pesananList.forEach((p, i) => {
const selectedDate = new Date(p.tgl);
const now = new Date();
@ -296,6 +314,9 @@ function renderCartSummary() {
const disableSore = isToday && jam >= 13;
const countDate = pesananList.length;
if(checkout_biodata.jenis_customer === 'Karyawan RSAB Harapan Kita'){
$("#karywan").re
}
pesananHTML += `
<div class="rounded border p-3 mb-3 shadow-sm" data-item-id="${item.id}" data-index="${i}">
<div class="row g-3 align-items-center">
@ -559,26 +580,51 @@ function validateStepOne() {
const email = document.getElementById('email').value.trim();
if (!jenisCustomer) {
alert('Silakan pilih jenis customer.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan pilih jenis customer.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!namaPemesan) {
alert('Silakan isi nama pemesan.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi nama pemesan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!jenisKelamin) {
alert('Silakan pilih jenis kelamin.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan pilih jenis kelamin.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!noWA) {
alert('Silakan isi nomor WhatsApp.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi nomor WhatsApp.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!email) {
alert('Silakan isi email terlebih dahulu.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi email terlebih dahulu.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
@ -587,7 +633,12 @@ function validateStepOne() {
if (selected === 'Karyawan RSAB Harapan Kita') {
const bagian = document.getElementById('bagian_instalasi').value.trim();
if (!bagian) {
alert('Silakan lengkapi data karyawan.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan lengkapi data karyawan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
} else if (selected === 'Keluarga Pasien / Penunggu Pasien') {
@ -596,13 +647,23 @@ function validateStepOne() {
const noKamar = document.getElementById('no_kamar').value.trim();
const kelas = document.getElementById('kelas_perawatan').value;
if (!namaPasien || !ruang || !noKamar || !kelas) {
alert('Silakan lengkapi data pasien.');
Swal.fire({
title: 'Perhatian!',
text: 'Silakan lengkapi data pasien.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
}else if(selected === "Masyarakat Umum"){
const alamat = document.getElementById('alamat').value;
if(!alamat){
alert('Silahkan lengkapi alamat')
Swal.fire({
title: 'Perhatian!',
text: 'Silahkan lengkapi alamat.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false
}
}
@ -617,10 +678,10 @@ function validateCartBeforeSubmit() {
let errorMessage = "";
cart.forEach((item, index) => {
const pesananList = item.pesanan || [];
pesananList.forEach((pesanan, i) => {
console.log(!pesanan.karbohidrat_id, !item?.apakah_someday);
if (!pesanan.tgl) {
isValid = false;
errorMessage = `Tanggal belum diisi pada item "${item.nama_menu}" (baris ${i + 1})`;
@ -836,6 +897,11 @@ document.getElementById('submitNote').addEventListener('click', function(e){
sessionStorage.setItem('cart', JSON.stringify(cart));
$("#notedPOrder").modal('hide')
}else{
alert('gagal menyimpan catatan')
Swal.fire({
title: 'Perhatian!',
text: 'gagal menyimpan catatan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
}
});

View File

@ -0,0 +1,20 @@
// $(document).ready(function () {
// getReminderOrder();
// });
// const getReminderOrder = () => {
// $.ajax({
// url: `/dashboard/count/pending`,
// success: function (response) {
// const button = document.getElementById("konfirmasi_pesanan");
// let count = response.count;
// button.classList.remove('d-none');
// if(count === 0){
// button.classList.add('d-none');
// }
// button.innerText = count;
// },
// });
// };

View File

@ -23,6 +23,23 @@ $(document).ready(function(){
filterState.jenis_menu = jenis
fetchMenu(filterState)
})
$(".alert-link").on('click', function(e){
e.preventDefault();
$('#tabJenisMenu .nav-link').removeClass('active text-success').addClass('text-black');
$('#tabJenisMenu .nav-link[data-filter="konsultasi" ]').removeClass('text-black').addClass('active text-success');
if (typeof datePicker !== 'undefined') {
datePicker.clear();
}
filterState.jenis_menu = 'konsultasi';
document.getElementById('tanggalTerpilihLabel').classList.add('d-none'); // Sembunyikan label
document.getElementById('tanggalTerpilihLabel').textContent = '';
document.getElementById('resetTanggal').classList.add('d-none');
fetchMenu(filterState);
})
let searchTimout;
$('#searchMenu').on('input', function(){

View File

@ -8,7 +8,6 @@
function fetchMenu(filter = {}) {
const containerGuest = $("#order_guest_id");
$("#tanggal-filter").removeClass('d-none');
if(filter.jenis_menu === "konsultasi"){

View File

@ -34,7 +34,7 @@
align: 'center',
valign: 'middle',
formatter: function (value, row, index) {
return `<input type="checkbox" class="rowCheckbox" data-order_id="${row.order_id}" />`
return `<input type="checkbox" class="rowCheckbox" data-order_detail_id="${row.order_id}" data-jenis_customer="${row?.order?.jenis_customer}" />`
}
},
{
@ -56,6 +56,11 @@
<i class="fa-solid fa-circle-info"></i>
</button>
`
buttons += `
<button class="btn btn-sm btn-primary me-2" onclick="cetak('${row?.order_detail_id}', '${row?.order?.jenis_customer}')">
<i class="fa-solid fa-qrcode"></i>
</button>
`
return `
<div class="d-flex space-x">
@ -129,23 +134,25 @@
const isChecked = this.checked;
$('.rowCheckbox').each(function () {
this.checked = isChecked;
let order_id = $(this).data('order_id');
let order_detail_id = $(this).data('order_detail_id');
let jenis_customer = $(this).data('jenis_customer');
if (isChecked) {
selectedRows.push({ order_id });
selectedRows.push({ order_detail_id, jenis_customer });
}
});
$('#buttonLabel').prop("disabled", !isChecked);
});
$(document).on('change', '.rowCheckbox', function () {
let order_id = $(this).data('order_id');
let order_detail_id = $(this).data('order_id');
let jenis_customer = $(this).data('jenis_customer');
let isChecked = this.checked;
if (isChecked) {
if (!selectedRows.find(r => r.order_id === order_id)) {
selectedRows.push({ order_id });
if (!selectedRows.find(r => r.order_detail_id === order_detail_id)) {
selectedRows.push({ order_detail_id, jenis_customer });
}
} else {
selectedRows = selectedRows.filter(r => r.order_id !== order_id);
selectedRows = selectedRows.filter(r => r.order_detail_id !== order_detail_id);
}
$('#buttonLabel').prop("disabled", selectedRows.length === 0);
});
@ -187,3 +194,7 @@
}
function cetak(id, jenis_customer){
console.log(id, jenis_customer);
}

View File

@ -47,7 +47,7 @@ document.getElementById('formActionOrder').addEventListener('submit', function (
showConfirmButton: false,
backdrop: true,
});
getReminderOrder();
datatablePending.bootstrapTable('refresh');
modalActionOrder.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
};
@ -119,6 +119,7 @@ document.getElementById('formActionApproveBillingOrder').addEventListener('submi
showConfirmButton: false,
backdrop: true,
});
getReminderOrder();
datatablePending.bootstrapTable('refresh');
modalActionApproveBillingnOrder.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
};

View File

@ -119,6 +119,7 @@
<script src="{{ ver('/assets/vendor/js/bootstrap.js') }}"></script>
<script src="{{ ver('/assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') }}"></script>
<script src="{{ ver('/assets/vendor/js/menu.js') }}"></script>
<script src="{{ ver('/js/count/konfirmasiPesanan.js') }}"></script>
<!-- endbuild -->

View File

@ -61,11 +61,11 @@
<!-- Components -->
<li class="menu-header small text-uppercase"><span class="menu-header-text">Order</span></li>
<!-- Cards -->
<li class="menu-item {{ Request::is('dashboard/pending') ? 'active' : '' }}">
<a href="/dashboard/pending" class="menu-link">
<i class="menu-icon tf-icons bx bx-collection"></i>
<div data-i18n="Basic">Konfirmasi Pesanan</div>
<div data-i18n="Basic">Konfirmasi Pesanan</div>
</a>
</li>
<!-- User interface -->
@ -78,10 +78,10 @@
<li class="menu-header small text-uppercase"><span class="menu-header-text">Verifikasi Makanan</span></li>
<li class="menu-item {{ Request::is('dashboard/pekerjaan') ? 'active' : '' }}">
<a href="/dashboard/pekerjaan" class="menu-link">
<i class="menu-icon tf-icons bx bx-collection"></i>
<div data-i18n="Basic">Verifikasi Makanan</div>
</a>
<a href="/dashboard/pekerjaan" class="menu-link">
<i class="menu-icon tf-icons bx bx-collection"></i>
<div data-i18n="Basic">Verifikasi Makanan</div>
</a>
</li>
</ul>
</aside>

View File

@ -15,7 +15,7 @@
<button type="button" class="btn btn-success next-step" id="btnSimpanPemesanan">Lanjutkan</button>
</div>
<div class="alert alert-info py-3 px-4 small border-start border-4 border-primary mt-3" role="alert">
<div class="alert alert-info py-3 px-4 small border-start border-4 border-primary mt-3 d-none" id="karyawan" role="alert">
<div class="fw-bold mb-2">
<i class="fa fa-info-circle me-1"></i>Informasi Penting
</div>
@ -50,4 +50,33 @@
</li>
</ul>
</div>
<div class="alert alert-info py-3 px-4 small border-start border-4 border-primary mt-3 d-none" id="pasien" role="alert">
<div class="fw-bold mb-2">
<i class="fa fa-info-circle me-1"></i>Informasi Penting
</div>
<ul class="mb-0 ps-3">
<li>
<strong>Menu Normal:</strong> Dipesan maksimal H-1 sebelum pukul <strong>13.00 WIB</strong>.
</li>
<li>
<strong>Menu Same Day:</strong> Dipesan pada hari yang sama setelah pukul <strong>13.00 WIB</strong>.
<ul class="ps-3 mt-1">
<li><strong>Makan Siang:</strong> maksimal pukul <strong>10.00 WIB</strong></li>
<li><strong>Makan Sore:</strong> maksimal pukul <strong>13.00 WIB</strong></li>
</ul>
</li>
<li>
Pemesanan tidak dapat dibatalkan dan tidak ada pengembalian uang.
</li>
<li>
Jenis karbohidrat dapat dipilih sesuai pilihan yang tersedia.
</li>
<li>
Butuh bantuan? Hubungi WhatsApp <strong>Instalasi Gizi</strong>:
<a href="https://wa.me/08815611382 " target="_blank">08815611382 </a> <br>
<small class="text-muted">Jam kerja: 08.00 15.00 WIB</small>
</li>
</ul>
</div>
</div>

View File

@ -19,7 +19,7 @@
</div>
</div>
</div>
<div class="row ms-1" id="tanggal-filter">
<div class="row ms-1" id="tanggal-filter">
<div class="col-12 mb-2">
<h6 class="fw-bold text-muted mb-1">
Pilih Tanggal Makanan
@ -57,30 +57,61 @@
<i class="fa fa-calendar-check text-success me-1"></i>
<span id="labelTanggalText">Menampilkan menu...</span>
</div>
</div>
<div class="alert alert-info d-flex align-items-center mb-3 shadow-sm rounded-3" role="alert">
<i class="fa fa-user-md fa-lg me-2 text-primary"></i>
<div>
<strong>Konsultasi Gizi!</strong><br>
Butuh rekomendasi menu sesuai kondisi Anda?
<a href="#" class="alert-link">Lihat jadwal konsultasi & daftar sekarang</a>.
</div>
</div>
</div>
<div id="order_guest_id"></div>
<div id="floatingCartButton"
class="cart-floating bg-success text-white rounded d-none shadow-lg"
onclick="checkout()"
style="cursor: pointer; position: fixed; bottom: 15px; left: 50%; transform: translateX(-50%); z-index: 1050; width: 90%; max-width: 500px;">
<div class="d-flex justify-content-between align-items-center px-3 py-2">
<div>
<strong><span id="floatingCartCount">0</span> item</strong><br>
<small id="floatingCartDesc">Isi keranjang anda</small>
</div>
<div class="d-flex align-items-center">
<div class="btn btn-light btn-sm">
<i class="fa-solid fa-cart-shopping text-success"></i>
<div id="floatingCartButton"
class="cart-floating bg-success text-white rounded d-none shadow-lg"
onclick="checkout()"
style="cursor: pointer; position: fixed; bottom: 15px; left: 50%; transform: translateX(-50%); z-index: 1050; width: 90%; max-width: 500px;">
<div class="d-flex justify-content-between align-items-center px-3 py-2">
<div>
<strong><span id="floatingCartCount">0</span> item</strong><br>
<small id="floatingCartDesc">Isi keranjang anda</small>
</div>
<div class="d-flex align-items-center">
<div class="btn btn-light btn-sm">
<i class="fa-solid fa-cart-shopping text-success"></i>
</div>
</div>
</div>
</div>
</div>
<div class="alert alert-info py-3 px-4 small border-start border-4 border-primary mt-3" role="alert">
<div class="fw-bold mb-2">
<i class="fa fa-info-circle me-1"></i>Informasi Penting
</div>
<ul class="mb-0 ps-3">
<li>
<strong>Menu Normal:</strong> Dipesan maksimal H-1 sebelum pukul <strong>13.00 WIB</strong>.
</li>
<li>
<strong>Menu Same Day:</strong> Dipesan pada hari yang sama setelah pukul <strong>13.00 WIB</strong>.
<ul class="ps-3 mt-1">
<li><strong>Makan Siang:</strong> maksimal pukul <strong>10.00 WIB</strong></li>
<li><strong>Makan Sore:</strong> maksimal pukul <strong>13.00 WIB</strong></li>
</ul>
</li>
<li>
Butuh bantuan? Hubungi WhatsApp <strong>Instalasi Gizi</strong>:
<a href="https://wa.me/08815611382 " target="_blank">08815611382 </a> <br>
<small class="text-muted">Jam kerja: 08.00 15.00 WIB</small>
</li>
</ul>
</div>
</div>
</section>

View File

@ -44,6 +44,7 @@ Route::group(['middleware' => ['auth']], function(){
Route::get('/datatable/menu', [MenuController::class, 'datatable']);
Route::get('/pending', [PesananController::class, 'index']);
Route::get('count/pending', [PesananController::class, 'countPesananPending']);
Route::get('datatable/pending', [PesananController::class, 'getDataPending']);
Route::post('pending/export', [PesananController::class, 'exportPending']);
Route::put('/pending/action/{order_id}', [PesananController::class, 'actionOrder']);