1080 lines
40 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// =======================
// DATA SETUP
// =======================
let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}');
let order_id = sessionStorage.getItem('order_id') || '[]';
// =======================
// EVENT ON LOAD
// =======================
document.addEventListener('DOMContentLoaded', () => {
const checkCart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const validChart = checkCart.length > 0 && checkCart.every(item =>
Array.isArray(item.pesanan) &&
item.pesanan.length > 0
);
if(!validChart){
window.location.href ='/';
return
}
$("#cartButton").addClass('d-none');
$("#no_order_result").val(order_id)
let currentStep = 0;
let orderDate=''
let deadline=''
let time_order=''
// Setup button step
document.querySelectorAll('.next-step').forEach(btn => {
btn.addEventListener('click', async () => {
const btnLoad = btn;
btnLoad.disabled = true;
btnLoad.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Memproses...';
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
try {
if (cart.length === 0) {
window.location.href = "/";
return;
}
if (currentStep === 0){
if(!validateStepOne()) return
isiKonfirmasi();
currentStep++; showStep(currentStep);
}else if(currentStep === 1){
const {isValid, errorMessage} =validateCartBeforeSubmit();
if (!isValid) {
Swal.fire({
title: 'Perhatian!',
text: errorMessage,
icon: 'warning',
confirmButtonText: 'Oke'
})
return
}
let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}');
if (!checkout_biodata.nama_pemesan) {
Swal.fire({
title: 'Biodata Belum Terisi!',
text: 'Lakukan Pengisian biodata terlebih dahulu.',
icon: 'warning',
confirmButtonText: 'oke!',
}).then(() => {
window.location.href = "/checkout";
});
return
}
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
for (const item of cart) {
for (const p of item.pesanan) {
const result = validateTanggalPemesanan(item, p.tgl);
if (!result.valid) {
alert(result.message);
return; // hentikan di sini, tidak lanjut
}
}
}
if (!sessionStorage.getItem('order_id')) {
await submitOrderToServer(); // async function simpan ke server
}
time_order = sessionStorage.getItem('time_order')
orderDate = new Date(time_order);
deadline = new Date(orderDate.getTime() + 10 * 60 * 1000)
updateCountdown()
currentStep++;
showStep(currentStep)
}else if(currentStep === 2){
renderCartSummary()
}
} catch (error) {
console.error(error);
Swal.fire('Error', 'Terjadi kesalahan, silakan coba lagi.', 'error');
}finally{
btnLoad.disabled = false;
btnLoad.innerHTML = 'Selanjutnya';
}
});
});
document.querySelectorAll('.prev-step').forEach(btn => {
btn.addEventListener('click', () => {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
if (cart.length === 0) {
window.location.href = "/";
return;
}
if (currentStep > 0) {
currentStep--;
showStep(currentStep);
}
});
});
// Inisialisasi tampilan dan data
renderCartSummary();
showStep(currentStep);
isiKonfirmasi();
toggleCustomerFields()
document.getElementById('no_order_display').textContent = order_id
const countDownPayment = document.getElementById('countdownPayment')
function orderTimeCheck(){
const checkTimeOrder = sessionStorage.getItem('time_order');
if (checkTimeOrder) {
const orderTime = new Date(checkTimeOrder);
const now = new Date();
// Jika time_order tidak valid (misalnya null, NaN, atau invalid date)
if (isNaN(orderTime.getTime())) {
console.warn('Waktu order tidak valid di session.');
sessionStorage.clear(); // bisa juga removeItem satu per satu
window.location.href = "/";
return;
}
const selisihMs = now.getTime() - orderTime.getTime();
const selisihMenit = selisihMs / 1000 / 60;
if (selisihMenit > 10) {
// Bersihkan session
sessionStorage.removeItem('cart');
sessionStorage.removeItem('checkout_biodata');
sessionStorage.removeItem('order_id');
sessionStorage.removeItem('time_order');
Swal.fire({
title: 'Waktu pembayaran sudah lewat!',
text: 'Silakan lakukan pemesanan ulang.',
icon: 'warning',
confirmButtonText: 'Oke'
}).then(() => {
window.location.href = "/";
});
return;
}
}
}
function updateCountdown(){
const now = new Date();
orderDate = new Date(time_order);
deadline = new Date(orderDate.getTime() + 10 * 60 * 1000)
const distance = deadline - now
if(distance <= 0){
countDownPayment.textContent = "Waktu Habis Lakukan Pemesanan Ulang";
return;
}
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60))
const seconds = Math.floor((distance % (1000 * 60)) / 1000)
countDownPayment.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
}
updateCountdown();
orderTimeCheck();
const interval = setInterval(() => {
updateCountdown()
orderTimeCheck()
if(new Date() >= deadline) clearInterval(interval)
}, 1000)
});
// =======================
// FUNGSI STEP
// =======================
const steps = document.querySelectorAll('.form-step');
const progressBar = document.getElementById('stepProgressBar');
function showStep(index) {
steps.forEach((step, i) => {
step.classList.toggle('active', i === index);
step.classList.toggle('d-none', i !== index);
});
const total = steps.length;
const progress = ((index + 1) / total) * 100;
progressBar.style.width = progress + '%';
progressBar.innerText = `Langkah ${index + 1} dari ${total}`;
for(let i = 1; i <= total; i++){
const circle = document.getElementById(`step-circle-${i}`)
if(circle){
circle.classList.toggle('active', i === index + 1)
}
}
}
// =======================
// FUNGSI BIODATA
// =======================
function toggleCustomerFields() {
const selected = $('input[name="jenis_customer"]:checked').val();
const $nama = $('#nama_pemesan');
// Sembunyikan semua section
$('.karyawan, .pasien, .umum').hide();
// Destroy jika sudah ada selectize
if ($nama[0] && $nama[0].selectize) {
$nama[0].selectize.destroy();
}
switch (selected) {
case 'Karyawan RSAB Harapan Kita':
$('.karyawan').show();
$nama.val('')
$nama.removeClass('form-control')
$("#help_nama_pemesan").removeClass('d-none')
$("#help_email_karyawan").removeClass('d-none')
selectKaryawan(); // inisialisasi ulang selectize
break;
case 'Keluarga Pasien / Penunggu Pasien':
$('.pasien').show();
$nama.addClass('form-control')
$("#help_nama_pemesan").addClass('d-none')
$("#help_email_karyawan").addClass('d-none')
break;
default: // Masyarakat Umum
$('.umum').show();
$nama.addClass('form-control')
$("#help_nama_pemesan").addClass('d-none')
$("#help_email_karyawan").addClass('d-none')
break;
}
}
$('input[name="jenis_customer"]').on('change', toggleCustomerFields);
toggleCustomerFields();
if (typeof checkout_biodata === 'object') {
if (checkout_biodata.jenis_customer) {
$(`input[name="jenis_customer"][value="${checkout_biodata.jenis_customer}"]`).prop('checked', true);
}
if(checkout_biodata.jenis_kelamin){
$(`input[name="jenis_kelamin"][value="${checkout_biodata.jenis_kelamin}"]`).prop('checked', true);
}
if(checkout_biodata.jenis_customer !== 'Karyawan RSAB Harapan Kita'){
$('#nama_pemesan').val(checkout_biodata.nama_pemesan);
}
// $('#tanggal_lahir').val(checkout_biodata.tanggal_lahir);
$('#tinggi_badan').val(checkout_biodata.tinggi_badan);
$('#berat_badan').val(checkout_biodata.berat_badan);
$('#no_whatsapp').val(checkout_biodata.no_whatsapp);
$('#nama_pasien').val(checkout_biodata.nama_pasien);
$('#ruang_perawatan').val(checkout_biodata.ruang_perawatan);
$('#no_kamar').val(checkout_biodata.no_kamar);
$('#kelas_perawatan').val(checkout_biodata.kelas_perawatan);
$('#bagian_instalasi').val(checkout_biodata.bagian_instalasi);
$('#no_ekstensien').val(checkout_biodata.no_ekstensien);
$('#email').val(checkout_biodata.email);
$('#alamat').val(checkout_biodata.alamat);
}
function isiKonfirmasi() {
const biodata = {
jenis_customer: $('input[name="jenis_customer"]:checked').val(),
nama_pemesan: $('#nama_pemesan').val(),
jenis_kelamin: $('input[name="jenis_kelamin"]:checked').val(),
id_karyawan: $('#id_karyawan').val(),
tinggi_badan: $('#tinggi_badan').val(),
berat_badan: $('#berat_badan').val(),
no_whatsapp: $('#no_whatsapp').val(),
nama_pasien: $('#nama_pasien').val(),
ruang_perawatan: $('#ruang_perawatan').val(),
no_kamar: $('#no_kamar').val(),
kelas_perawatan: $('#kelas_perawatan').val(),
bagian_instalasi: $('#bagian_instalasi').val(),
no_ekstensien: $('#no_ekstensien').val(),
email: $('#email').val(),
alamat: $('#alamat').val(),
};
sessionStorage.setItem('checkout_biodata', JSON.stringify(biodata));
checkout_biodata = biodata;
renderCartSummary();
}
// =======================
// FUNGSI CART / PESANAN
// =======================
function renderCartSummary() {
const container = document.getElementById('checkout_cart_summary');
container.innerHTML = '';
let totalKeseluruhan = 0;
const carts = JSON.parse(sessionStorage.getItem('cart') || '[]');
const checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '[]');
carts.forEach((item) => {
const pesananList = Array.isArray(item.pesanan) ? item.pesanan : [];
let pesananHTML = '';
const harga = checkout_biodata.jenis_customer === 'Karyawan RSAB Harapan Kita'
? item.harga_karyawan || 0
: item.harga_public || 0;
const itemTotal = pesananList.reduce((sum, p) => sum + (p.jumlah * harga), 0);
if (checkout_biodata.jenis_customer === "Karyawan RSAB Harapan Kita") {
$('#karyawan').removeClass('d-none');
$('#pasien').addClass('d-none');
} else if (checkout_biodata.jenis_customer === "Keluarga Pasien / Penunggu Pasien") {
$('#karyawan').addClass('d-none');
$('#pasien').removeClass('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();
const isToday = selectedDate.toDateString() === now.toDateString();
const jam = now.getHours();
const disableSiang = isToday && jam >= 10;
const disableSore = isToday && jam >= 13;
const countDate = pesananList.length;
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">
<!-- Note -->
<div class="col-12 col-md-2">
<button type="button" class="btn btn-outline-success" onclick="notedOrder(${item.id}, ${i})" title="Catatan">
<i class="fa-solid fa-note-sticky"></i> Catatan
</button>
</div>
<!-- Tanggal -->
<div class="col-12 col-md-2">
<input type="text" class="form-control form-control-sm tanggal-input" id="tanggal-${item.id}-${i}" readonly placeholder="Pilih Tanggal">
</div>
<!-- Karbohidrat -->
${item.apakah_someday ? `` : `
<div class="col-12 col-md-3">
<select class="form-select form-select-sm karbohidrat-input" onChange="onKarbohidratChange(${item.id}, ${i}, this, ${item.kalori})">
<option disabled selected>Pilih Karbohidrat</option>
${(karhohidrats || []).map(k => `
<option value="${k.karbohidrat_id}" ${p.karbohidrat_id === k.karbohidrat_id ? 'selected' : ''} data-kalori=${k.nilai_kalori}>
${k.nama_karbohidrat} ${k.nilai_kalori ? `(${k.nilai_kalori} kal)` : ''}
</option>
`).join('')}
</select>
</div>`}
<!-- Waktu Makan -->
<div class="col-12 col-md-2">
<select class="form-select form-select-sm kategori-pemesanan-input"
data-item-id="${item.id}" data-index="${i}"
onchange="onKategoriChange(${item.id}, ${i}, ${isToday})"
onfocus="this.dataset.previousValue = this.value"
${item.apakah_menu_siang || item.apakah_menu_sore ? '' : 'disabled'}>
${
item.apakah_someday
? (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''} ${disableSiang ? 'disabled' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''} ${disableSore ? 'disabled' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected ${disableSiang ? 'disabled' : ''}>Makan Siang</option>`
: item.apakah_menu_sore
? `<option value="Makan Sore" selected ${disableSore ? 'disabled' : ''}>Makan Sore</option>`
: `<option value="" disabled selected>Tidak tersedia</option>`
)
: (
item.apakah_menu_siang && item.apakah_menu_sore
? `
<option value="Makan Siang" ${p.kategoriPemesanan === 'Makan Siang' ? 'selected' : ''}>Makan Siang</option>
<option value="Makan Sore" ${p.kategoriPemesanan === 'Makan Sore' ? 'selected' : ''}>Makan Sore</option>
`
: item.apakah_menu_siang
? `<option value="Makan Siang" selected>Makan Siang</option>`
: item.apakah_menu_sore
? `<option value="Makan Sore" selected>Makan Sore</option>`
: `<option value="" disabled selected>Tidak tersedia</option>`
)
}
</select>
</div>
<!-- Jumlah -->
<div class="col-6 col-md-2">
<div class="d-flex align-items-center justify-content-between">
<button class="btn btn-sm btn-outline-success" onclick="decrement(${item.id}, ${i})" ${p.jumlah > 1 ? '' : 'disabled'}>
<i class="fa fa-minus"></i>
</button>
<input type="text" class="form-control form-control-sm text-center mx-2 jumlah-input"
value="${p.jumlah}" readonly style="width: 60px;" id="jumlah-${item.id}-${i}">
<button class="btn btn-sm btn-outline-success" onclick="increment(${item.id}, ${i})">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<!-- Tombol Hapus -->
<div class="col-6 col-md-1 text-end">
${countDate > 1
? `<button class="btn btn-sm btn-danger" onclick="removeOrderDate(${item.id}, ${i}, ${countDate})" title="Hapus">
<i class="fa fa-trash"></i>
</button>`
: ''
}
</div>
${item.kalori
? `<div class="mb-2 small text-muted">Total Kalori: <strong id="kalori_${item.id}_${i}">${p?.resultKalori ? p?.resultKalori : item?.kalori}</strong> kal</div>`
: ''}
</div>
</div>
`;
});
const itemHTML = `
<div class="card mb-3 shadow-sm position-relative">
<button type="button" class="btn btn-sm btn-danger position-absolute top-0 end-0 m-2" onClick="removeCartItem(${item.id})" style="z-index:1;">
Hapus
</button>
<div class="d-flex flex-column flex-md-row">
<div class="p-2 d-flex justify-content-center align-items-center" style="flex: 0 0 300px;">
<img src="gambar/${item.foto || 'default.jpg'}" alt="${item.nama_menu}"
class="img-fluid rounded" style="max-height: 280px; width: 100%; object-fit: cover;">
</div>
<div class="flex-grow-1 position-relative">
<div class="card-body">
<!-- Judul menu -->
<h4 class="card-title mb-2 fw-bold text-primary">${item.nama_menu}</h4>
<!-- Harga -->
<div class="badge bg-success-subtle text-success fw-bold fs-6 mb-2">
${checkout_biodata?.jenis_customer === "Karyawan RSAB Harapan Kita"
? '<span class="me-1">Harga Karyawan</span>'
: '<span class="me-1">Harga</span>'
}
Rp ${parseInt(harga).toLocaleString('id-ID')}
</div>
<!-- Kalori -->
${item?.kalori ? `<div class="text-muted small mb-1"><i class="fas fa-fire me-1"></i>Kalori: ${item.kalori} kal</div>` : ''}
<!-- Deskripsi -->
${item.deskripsi ? `<p class="card-text text-muted small mb-2">${item.deskripsi}</p>` : ''}
<!-- Info tanggal & jenis menu -->
<div class="d-flex flex-column gap-1 mb-2">
<div class="small text-muted">
<i class="fas fa-calendar-check me-1"></i>
${item.apakah_someday
? 'Tersedia setiap hari (Senin Minggu)'
: (item.tgl_tersedia ? `Tersedia pada tanggal: ${item.tgl_tersedia}` : 'Tidak ada info tanggal tersedia')
}
</div>
<div class="small text-muted">
<i class="fas fa-utensils me-1"></i>
<strong>${item.apakah_someday ? 'Sameday' : 'Menu Normal'}</strong>
</div>
</div>
<!-- Petunjuk -->
<div class="alert alert-info small p-2 mb-2">
<strong>Petunjuk:</strong> Isi tanggal pemesanan, pilih karbohidrat, dan catatan tambahan (opsional).
</div>
<!-- Form pesanan -->
${pesananHTML}
<!-- Tombol & total -->
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mt-3">
<button class="btn btn-sm btn-success" onclick="addOrderDate(${item.id}, ${item.apakah_menu_sore})">
<i class="fas fa-plus me-1"></i>Tambah Tanggal
</button>
<div class="fw-bold">
Total: <span class="text-success">Rp ${itemTotal.toLocaleString('id-ID')}</span>
</div>
</div>
</div>
</div>
</div>
</div>
`;
container.insertAdjacentHTML('beforeend', itemHTML);
pesananList.forEach((p, i) => initFlatpickrTersedia(item, i));
});
container.insertAdjacentHTML('beforeend', `
<div class="text-end mt-4">
<hr>
<h5><strong>Total Keseluruhan:</strong> <span class="text-success">Rp ${totalKeseluruhan.toLocaleString('id-ID')}</span></h5>
</div>
`);
document.getElementById('no_order_price').textContent = 'Rp ' + totalKeseluruhan.toLocaleString('id-ID');
}
// =======================
// EVENT HANDLER FIELD
// =======================
function onJumlahChange(itemId, index) {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .jumlah-input`);
if (!isNaN(input.value)) {
cart.find(item => item.id === itemId).pesanan[index].jumlah = parseInt(input.value);
sessionStorage.setItem('cart', JSON.stringify(cart));
isiKonfirmasi();
}
}
function onTanggalChange(itemId, index) {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .tanggal-input`);
cart.find(item => item.id === itemId).pesanan[index].tgl = input.value;
sessionStorage.setItem('cart', JSON.stringify(cart));
renderCartSummary();
}
function onKarbohidratChange(itemId, index, el, kalori){
const selectedOption = el.options[el.selectedIndex];
const kaloriOption = parseInt(selectedOption.getAttribute('data-kalori')) || 0;
const kaloriMenuInt = kalori || 0;
const totalKalori = kaloriOption + kaloriMenuInt;
const kaloriEl = document.getElementById(`kalori_${itemId}_${index}`);
if (kaloriEl) {
kaloriEl.textContent = totalKalori ;
}
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .karbohidrat-input`);
cart.find(item => item.id === itemId).pesanan[index].karbohidrat_id = parseInt(input.value);
cart.find(item => item.id === itemId).pesanan[index].resultKalori = totalKalori;
sessionStorage.setItem('cart', JSON.stringify(cart));
}
function onKategoriChange(itemId, index, isToday) {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const selectEl = document.querySelector(`.kategori-pemesanan-input[data-item-id='${itemId}'][data-index='${index}']`);
const kategori = selectEl.value;
let now = new Date();
let jam = now.getHours();
if (kategori === "Makan Siang" && isToday && jam >= 10) {
alert("Pemesanan Makan Siang hanya bisa dilakukan sebelum jam 10:00.");
} else if (kategori === "Makan Sore" && isToday && jam >= 13) {
alert("Pemesanan Makan Sore hanya bisa dilakukan sebelum jam 13:00.");
}
const item = cart.find(item => item.id === itemId);
if (item && item.pesanan && item.pesanan[index]) {
item.pesanan[index].kategoriPemesanan = kategori;
sessionStorage.setItem('cart', JSON.stringify(cart));
// renderCartSummary();
}
}
// =======================
// TAMBAH / HAPUS PESANAN
// =======================
function addOrderDate(itemId, sore) {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item = cart.find(i => i.id === itemId);
if (item && Array.isArray(item.pesanan)) {
item.pesanan.push({
tgl: '',
jumlah: 1,
kategoriPemesanan: sore ? 'Makan Sore' : 'Makan Siang'
});
sessionStorage.setItem('cart', JSON.stringify(cart));
renderCartSummary();
}
}
function removeOrderDate(itemId, index, count) {
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item = cart.find(i => i.id === itemId);
if(count == 1){
cart = cart.filter(i => i.id !== itemId);
sessionStorage.setItem('cart', JSON.stringify(cart));
}else if(item && Array.isArray(item.pesanan) && item.pesanan.length > index) {
item.pesanan.splice(index, 1);
sessionStorage.setItem('cart', JSON.stringify(cart));
}
renderCartSummary();
}
function removeCartItem(itemId){
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
cart = cart.filter(i => i.id !== itemId);
sessionStorage.setItem('cart', JSON.stringify(cart));
renderCartSummary()
}
// validasi step one dan sebelum submit
function validateStepOne() {
const jenisCustomer = document.querySelector('input[name="jenis_customer"]:checked');
const jenisKelamin = document.querySelector('input[name="jenis_kelamin"]:checked');
const namaPemesan = document.getElementById('nama_pemesan').value.trim();
const noWA = document.getElementById('no_whatsapp').value.trim();
const email = document.getElementById('email').value.trim();
if (!jenisCustomer) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan pilih jenis customer.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!namaPemesan) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi nama pemesan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!jenisKelamin) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan pilih jenis kelamin.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!noWA) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi nomor WhatsApp.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
if (!email) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan isi email terlebih dahulu.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
// Validasi tambahan sesuai jenis customer
const selected = jenisCustomer.value;
if (selected === 'Karyawan RSAB Harapan Kita') {
const bagian = document.getElementById('bagian_instalasi').value.trim();
if (!bagian) {
Swal.fire({
title: 'Perhatian!',
text: 'Silakan lengkapi data karyawan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false;
}
} else if (selected === 'Keluarga Pasien / Penunggu Pasien') {
const namaPasien = document.getElementById('nama_pasien').value.trim();
const ruang = document.getElementById('ruang_perawatan').value;
const noKamar = document.getElementById('no_kamar').value.trim();
const kelas = document.getElementById('kelas_perawatan').value;
if (!namaPasien || !ruang || !noKamar || !kelas) {
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){
Swal.fire({
title: 'Perhatian!',
text: 'Silahkan lengkapi alamat.',
icon: 'warning',
confirmButtonText: 'Oke'
})
return false
}
}
return true;
}
function validateCartBeforeSubmit() {
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
let isValid = true;
let errorMessage = "";
cart.forEach((item, index) => {
const pesananList = item.pesanan || [];
pesananList.forEach((pesanan, i) => {
if (!pesanan.tgl) {
isValid = false;
errorMessage = `Tanggal belum diisi pada item "${item.nama_menu}" (baris ${i + 1})`;
} else if (!pesanan.kategoriPemesanan) {
isValid = false;
errorMessage = `Kategori pemesanan belum dipilih pada item "${item.nama_menu}" (baris ${i + 1})`;
} else if (!pesanan.jumlah || pesanan.jumlah <= 0) {
isValid = false;
errorMessage = `Jumlah harus lebih dari 0 pada item "${item.nama_menu}" (baris ${i + 1})`;
}else if(!pesanan.karbohidrat_id && !item?.apakah_someday){
isValid = false;
errorMessage = `Karbohidrat belum diisi pada item "${item.nama_menu}" (baris ${i + 1})`
}
});
});
return { isValid, errorMessage };
}
function hitungTotalHarga(){
const biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}');
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
let total =0;
cart.forEach(item => {
const harga = biodata.jenis_customer === "Karyawan RSAB Harapan Kita" ? item.harga_karyawan : item.harga_public || 0
const itemTotal = item.pesanan?.reduce((sum, p) => sum + (p.jumlah * harga), 0);
total += itemTotal
})
return total;
}
function copyNoRek() {
const text = document.getElementById('noRekText').innerText;
navigator.clipboard.writeText(text).then(() => {
Swal.fire({
icon: 'success',
title: 'Disalin!',
text: 'Nomor rekening berhasil disalin: ' + text,
showConfirmButton: false,
timer: 1500
});
}).catch(err => {
console.error('Gagal menyalin: ', err);
Swal.fire({
icon: 'warning',
text: 'Gagal menyalin teks: ' + text,
showConfirmButton: false,
timer: 2000
});
});
}
function copyNoOrder() {
const text = document.getElementById('no_order_display').innerText;
navigator.clipboard.writeText(text).then(() => {
Swal.fire({
icon: 'success',
title: 'Disalin!',
text: 'Nomor order berhasil disalin: ' + text,
showConfirmButton: false,
timer: 1500
});
}).catch(err => {
console.error('Gagal menyalin: ', err);
Swal.fire({
icon: 'warning',
text: 'Gagal menyalin teks: ' + text,
showConfirmButton: false,
timer: 2000
});
});
}
function initFlatpickrTersedia(item, i) {
const now = new Date();
const jamFlat = now.getHours();
const menitFlat = now.getMinutes();
const totalMenitFlatSekarang = jamFlat * 60 + menitFlat;
const menitBatasFlat = 13 * 60;
const lewatBatasNormal = totalMenitFlatSekarang >= menitBatasFlat;
const tglString = Array.isArray(item?.tgl_tersedia)
? item?.tgl_tersedia.join(',') // kalau array → gabung jadi string
: String(item?.tgl_tersedia);
// Ambil string tgl_tersedia dan ubah jadi array tanggal lengkap
const dayNumbers = (tglString || "")
.split(',')
.map(s => s.trim())
.filter(s => s !== '' && !isNaN(s))
.map(s => parseInt(s));
// Generate tanggal dalam format YYYY-MM-DD untuk 3 bulan ke depan
let availableDates = [];
const bulanKeDepan = 3;
for (let bulanOffset = 0; bulanOffset < bulanKeDepan; bulanOffset++) {
const baseDate = new Date(now.getFullYear(), now.getMonth() + bulanOffset, 1);
const year = baseDate.getFullYear();
const month = String(baseDate.getMonth() + 1).padStart(2, '0');
dayNumbers.forEach(day => {
const dayStr = String(day).padStart(2, '0');
const fullDateStr = `${year}-${month}-${dayStr}`;
const fullDate = new Date(`${fullDateStr}T13:00:00`);
// Jika bukan menu someday, cek aturan H-1 dan jam batas
if (item.apakah_someday) {
availableDates.push(fullDateStr);
} else {
const selisihHari = Math.floor((fullDate - now) / (1000 * 60 * 60 * 24));
if (selisihHari >= 1 || (selisihHari === 1 && !lewatBatasNormal)) {
availableDates.push(fullDateStr);
}
}
});
}
let minTanggal = 'today';
// Jika item adalah someday dan waktu sekarang sudah lewat 13:00
if (item?.apakah_someday && totalMenitFlatSekarang >= 13 * 60) {
const besok = new Date(now);
besok.setDate(now.getDate() + 1);
minTanggal = besok.toISOString().split("T")[0]; // format YYYY-MM-DD
}
flatpickr(`#tanggal-${item.id}-${i}`, {
dateFormat: "Y-m-d",
...(item?.apakah_someday ? {minDate: minTanggal} : {enable:availableDates}),
defaultDate: item.pesanan[i]?.tgl || null,
disableMobile: true,
onChange: function(selectedDates, dateStr) {
onTanggalChange(item.id, i, dateStr);
}
});
}
function increment(itemId, index) {
const input = document.getElementById(`jumlah-${itemId}-${index}`);
input.value = parseInt(input.value || "0") + 1;
onJumlahChange(itemId, index); // Tetap panggil function milikmu
}
function decrement(itemId, index) {
const input = document.getElementById(`jumlah-${itemId}-${index}`);
let current = parseInt(input.value || "0");
if (current > 1) {
input.value = current - 1;
onJumlahChange(itemId, index);
}else{
return
}
}
function toggleBuktiPembayaran() {
const metode = document.getElementById("cara_pembayaran").value;
const buktiSection = document.getElementById("bukti_section");
const buktiInput = document.getElementById("bukti_pembayaran");
const billing_section = document.getElementById("billing_section");
buktiInput.required = true;
if (metode === "billing") {
buktiSection.style.display = "none";
billing_section.style.display = "block";
buktiInput.required = false;
$("#modalActionMethodBillingOrder").modal('show')
} else {
buktiSection.style.display = "block";
billing_section.style.display = "none";
buktiInput.required = true;
$("#modalActionMethodBillingOrder").modal('hide')
}
}
function validateTanggalPemesanan(item, tglDipilih) {
const now = new Date();
const jam = now.getHours();
const menit = now.getMinutes();
const totalMenit = jam * 60 + menit;
const batasWaktu = 13 * 60;
const tglSekarang = now.toISOString().split("T")[0];
if (item.apakah_someday && totalMenit >= batasWaktu && tglDipilih === tglSekarang) {
return {
valid: false,
message: `Maaf, Anda tidak bisa memilih hari ini (${tglDipilih}) untuk menu sameday karena sudah lewat jam 13:00`
};
}
return { valid: true };
}
function notedOrder(id, i) {
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item = cart.find(item => item.id === id);
const note = item?.pesanan?.[i]?.catatan || '';
$("#note_order").val(note);
$("#submitNote").data('id', id).data('index', i);
$("#notedPOrder").modal('show');
}
document.querySelectorAll('.auto-expand').forEach(function(textarea){
textarea.addEventListener('input', function () {
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
})
document.getElementById('submitNote').addEventListener('click', function(e){
e.preventDefault()
const id = $(this).data('id')
const index = $(this).data('index')
const noted = $("#note_order").val()
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
const item =cart.find(item => item.id === id)
if(item && item.pesanan && item.pesanan[index]){
item.pesanan[index].catatan = noted
sessionStorage.setItem('cart', JSON.stringify(cart));
$("#notedPOrder").modal('hide')
}else{
Swal.fire({
title: 'Perhatian!',
text: 'gagal menyimpan catatan.',
icon: 'warning',
confirmButtonText: 'Oke'
})
}
});
function selectKaryawan(){
const $el = $('#nama_pemesan');
// 1. destroy jika sudah ada
if ($el[0] && $el[0].selectize) {
$el[0].selectize.destroy();
}
$el.selectize({
valueField: 'label', // sama dengan labelField
labelField: 'label',
searchField: ['label'],
create: function(input) {
return {
label: input,
value: input
};
},
createOnBlur: true,
placeholder: "Cari nama karyawan...",
maxItems: 1,
load: function (query, callback) {
$.ajax({
url: '/karyawan',
data: { search: query },
success: res => callback(res.data || []),
error: () => callback([])
});
},
render: {
option: (item, escape) =>
`<div class="p-1"><div class="fw-semibold">${escape(item.label)}</div></div>`,
item: (item, escape) => `<div>${escape(item.label)}</div>`
}
});
}
selectUnitInstalasi()
function selectUnitInstalasi(){
const bagian_instalasi = $('#bagian_instalasi');
// 1. destroy jika sudah ada
if (bagian_instalasi[0] && bagian_instalasi[0].selectize) {
bagian_instalasi[0].selectize.destroy();
}
bagian_instalasi.selectize({
valueField: 'label',
labelField: 'label',
searchField: ['label'],
create: false,
sortField: [],
placeholder: "Cari unit instalasi...",
maxItems:1,
load: function (query, callback) {
$.ajax({
url: '/unit-instalasi',
data: { search: query },
success: function (response) {
if (response.error === 0 && Array.isArray(response.data)) {
callback(response.data);
} else {
callback();
}
},
error: function () {
callback();
}
});
},
render: {
option: function (item, escape) {
return `<div class="p-1">
<div class="fw-semibold" style="font-size: 0.85rem;">${escape(item.label)}</div>
</div>`;
},
item: function (item, escape) {
return `<div>${escape(item?.label)}</div>`;
}
}
});
}