progress pesanan order

This commit is contained in:
JokoPrasetio 2025-07-28 15:49:12 +07:00
parent 4bcbf84748
commit 80548af3a7
52 changed files with 795 additions and 143 deletions

View File

@ -7,6 +7,7 @@ use App\Models\OrderDetail;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class CustomerController extends Controller
{
@ -185,7 +186,7 @@ class CustomerController extends Controller
$today = now()->toDateString();
$jumlahHariIni = Order::whereDate('entry_at', $today)->count();
$urutan = $jumlahHariIni + 1;
$noOrder = 'TX/CT/GIZI/' . now()->year .'/'. now()->month .'/' . now()->day .'/' . str_pad($urutan, 4, '0', STR_PAD_LEFT);
$noOrder = 'TX/CT/GIZI/' . now()->year .'/'. now()->month .'/' . now()->day .'/' . Str::random(6) .'/' . str_pad($urutan, 4, '0', STR_PAD_LEFT);
$payloadOrder = [
'no_order' => $noOrder,
'jenis_customer' => $jenisCustomer,

View File

@ -2,8 +2,14 @@
namespace App\Http\Controllers;
use App\Models\KategoriKlasifikasiPaketMenu;
use App\Models\Menu;
use App\Models\TanggalMenuTersedia;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class MenuController extends Controller
{
@ -31,7 +37,77 @@ class MenuController extends Controller
*/
public function store(Request $request)
{
//
DB::connection('dbOrderGizi')->beginTransaction();
try {
$allData = request('data');
// dd($allData);
foreach ($allData as $data) {
$hargaPublic = $data['harga_public'] ? str_replace('.', '', $data['harga_public']) : null;
$hargaKaryawan = $data['harga_karyawan'] ? str_replace('.', '', $data['harga_karyawan']) : null;
$hargaKeluargaPasien = $data['harga_keluarga_pasien'] ? str_replace('.', '', $data['harga_keluarga_pasien']) : null;
$payload = [
'pegawai_id_entry' => auth()->user()->id,
'pegawai_nama_entry' => auth()->user()->full_name,
'nama_menu' => $data['nama'],
'jenis_menu' => $data['jenis_makanan'],
'harga_public' => $hargaPublic,
'harga_karyawan' => $hargaKaryawan,
'harga_keluarga_pasien' => $hargaKeluargaPasien,
'deskripsi' => $data['deskripsi'],
'status' => true,
'apakah_someday' => $data['kategori_menu'] === "Menu Normal" ? false : true,
'apakah_menu_siang' => (isset($data['apakah_menu_siang']) && $data['apakah_menu_siang'] === "iya") ? true : false,
'apakah_menu_sore' => (isset($data['apakah_menu_sore']) && $data['apakah_menu_sore'] === "iya") ? true : false,
];
if($data['foto']){
$imageName = Str::random(15) . '.' . $data['foto']->getClientOriginalExtension();
Storage::disk('img_menu')->put($imageName, file_get_contents($data['foto']));
$payload['foto'] =$imageName;
}
$menu = Menu::create($payload);
if(isset($data['kategori_diet_id'])){
$categories = $data['kategori_diet_id'];
foreach ($categories as $category) {
$payloadCategory = [
'pegawai_id_entry' => auth()->user()->id,
'pegawai_nama_entry' => auth()->user()->full_name,
'kategori_diet_id' => $category,
'master_menu_id' => $menu->master_menu_id,
];
KategoriKlasifikasiPaketMenu::create($payloadCategory);
}
}
if(isset($data['tanggal']) && ($data['kategori_menu'] === "Menu Normal")){
$tanggal = $data['tanggal'];
foreach ($tanggal as $tgl) {
$payloadTgl = [
'pegawai_id_entry' => auth()->user()->id,
'pegawai_nama_entry' => auth()->user()->full_name,
'tgl_harian' => $tgl,
'master_menu_id' => $menu->master_menu_id,
];
TanggalMenuTersedia::create($payloadTgl);
}
}
}
//code...
DB::connection('dbOrderGizi')->commit();
return response()->json([
'status' => true,
'message' => 'Menu berhasil ditambahkan!'
]);
} catch (\Throwable $th) {
dd($th);
DB::connection('dbOrderGizi')->rollBack();
return response()->json([
'status' => false,
'message' => 'Menu gagal ditambahkan!',
'errors' => $th->getMessage()
]);
}
}
/**
@ -63,10 +139,87 @@ class MenuController extends Controller
*/
public function destroy(string $id)
{
//
$data = Menu::where(['statusenabled' => true, 'master_menu_id' => $id])->first();
$payload = [
'statusenabled' => false,
'pegawai_id_entry' => auth()->user()->id,
'pegawai_nama_entry' => auth()->user()->full_name,
'modified_at' => Carbon::now()
];
$data->update($payload);
return response()->json([
'status' => true,
'message' => 'Berhasil menghapus data'
], 200);
}
public function datatable(){
return Menu::where('statusenabled', true)->get();
$data = DB::connection('dbOrderGizi')
->table('public.master_menu as mn')
->leftJoin('public.klasifikasi_menu_diet as kmd', 'kmd.master_menu_id', '=', 'mn.master_menu_id')
->leftJoin('public.kategori_diet as kd', 'kd.kategori_diet_id', '=', 'kmd.kategori_diet_id')
->leftJoin('public.detail_menu_paket_harian as dmph', 'dmph.master_menu_id', '=', 'mn.master_menu_id')
->where('mn.statusenabled', true)
->select(
'mn.master_menu_id',
'mn.nama_menu',
'mn.foto',
'mn.jenis_menu',
'mn.harga_public',
'mn.harga_karyawan',
'mn.harga_keluarga_pasien',
'mn.deskripsi',
'mn.status',
'mn.apakah_someday',
'mn.apakah_menu_siang',
'mn.apakah_menu_sore',
'kmd.klasifikasi_menu_diet_id',
'kmd.kategori_diet_id',
'kd.nama_kategori_diet',
'dmph.detail_menu_paket_harian_id',
'dmph.tgl_harian'
)
->get()->groupBy('master_menu_id');
$grouped = $data->map(function($items){
$first = $items->first();
$tglAvailable = $items->filter(fn($tgl) => $tgl->tgl_harian !== null)
->unique('detail_menu_paket_harian_id')
->map(function($item){
return [
'detail_menu_paket_harian_id' => $item->detail_menu_paket_harian_id,
'tgl_harian' => $item->tgl_harian,
];
})->values();
$kategoriDiet = $items->filter(fn($kd) => $kd->klasifikasi_menu_diet_id !== null)
->unique('klasifikasi_menu_diet_id')
->map(function($item){
return [
'klasifikasi_menu_diet_id' => $item->klasifikasi_menu_diet_id,
'nama_kategori_diet' => $item->nama_kategori_diet,
];
});
return [
'master_menu_id' => $first->master_menu_id,
'nama_menu' => $first->nama_menu,
'foto' => $first->foto,
'jenis_menu' => $first->jenis_menu,
'harga_public' => $first->harga_public,
'harga_karyawan' => $first->harga_karyawan,
'harga_keluarga_pasien' => $first->harga_keluarga_pasien,
'deskripsi' => $first->deskripsi,
'status' => $first->status,
'apakah_someday' => $first->apakah_someday,
'apakah_menu_siang' => $first->apakah_menu_siang,
'apakah_menu_sore' => $first->apakah_menu_sore,
'tgl' => $tglAvailable,
'kategoriDiet' => $kategoriDiet,
];
});
return response()->json([
'status' => true,
'rows' => $grouped->values(),
'total' => $grouped->count()
]);
}
}

View File

@ -56,6 +56,40 @@ class PesananController extends Controller
}
}
public function actionOrderViaBilling(Request $request, string $order_id){
DB::connection('dbOrderGizi')->beginTransaction();
try {
$order = Order::where('order_id', $order_id)->first();
$payload = [
'pegawai_id_confirm_order' => auth()->user()->id,
'pegawai_name_confirm_order' => auth()->user()->full_name,
'pegawai_at_confirm_order' => Carbon::now(),
'status_order' => 'Lunas',
'cara_pembayaran' => 'Billing'
];
$order->update($payload);
DB::connection('dbOrderGizi')->commit();
return response()->json([
'status' => true,
'message' =>'Konfirmasi Order Gizi telah disetujui!'
]);
} catch (\Throwable $th) {
DB::connection('dbOrderGizi')->rollBack();
return response()->json([
'status' => false,
'message' => 'Gagal melakukan Konfirmasi Order Gizi'
]);
//throw $th;
}
}
public function getDataOrderDetail($order_id){
$data = Order::with('orderDetail')->where('order_id', $order_id)->first();
return response()->json($data);
}
/**
* Show the form for creating a new resource.
*/

View File

@ -23,8 +23,12 @@ class Menu extends Model
'jenis_menu',
'harga_public',
'harga_karyawan',
'harga_keluarga_pasien',
'deskripsi',
'status'
'status',
'apakah_someday',
'apakah_menu_siang',
'apakah_menu_sore'
];
}

View File

@ -36,4 +36,9 @@ class Order extends Model
'bagian_instalasi',
'note_dibatalkan'
];
public function orderDetail(){
return $this->hasMany(OrderDetail::class, 'order_id')->with('paketMenu', 'menu');
}
}

View File

@ -23,4 +23,13 @@ class OrderDetail extends Model
'order_id',
'status_order'
];
public function menu(){
return $this->belongsTo(Menu::class, 'master_menu_id', 'master_menu_id')->select('master_menu_id', 'nama_menu', 'foto');
}
public function paketMenu(){
return $this->belongsTo(PaketMenu::class, 'master_paket_menu_id', 'master_paket_menu_id')->select('master_paket_menu_id', 'nama_paket', 'foto');
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TanggalMenuTersedia extends Model
{
protected $connection = 'dbOrderGizi';
protected $table = 'public.detail_menu_paket_harian';
public $timestamps = false;
protected $primaryKey = "detail_menu_paket_harian_id";
protected $fillable =[
'entry_at',
'pegawai_id_entry',
'pegawai_nama_entry',
'modified_at',
'pegawai_id_modified',
'pegawai_nama_modified',
'statusenabled',
'tgl_harian',
'master_paket_menu_id',
'master_menu_id'
];
}

View File

@ -59,6 +59,12 @@ return [
'throw' => false,
'report' => false,
],
'img_menu' => [
'driver' => 'local',
'root' => public_path('gambar') . '/',
'url' => env('APP_URL') . '/',
'visibility' => 'public',
],
],

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1 +1,4 @@
const datatableMasterMenu = $("#datatableMasterMenu")
const formAddMenu = $("#formMasterMenu")
const modalAddMenu = document.getElementById("modalMasterMenu")

View File

@ -1,127 +1,298 @@
document.addEventListener('DOMContentLoaded', function () {
const formSetsContainer = document.getElementById('form-sets-container');
const btnTambahForm = document.getElementById('btnTambahForm');
let countForm = 1; // karena form pertama pakai index 0
// Auto-expand textarea
function autoExpand(textarea) {
// Fungsi inisialisasi Selectize dan Auto-expand
function initSelectize(formElement) {
const kategoriSelect = formElement.querySelector('.tags-menu');
const tanggalSelect = formElement.querySelector('.date-input');
if (kategoriSelect) {
$(kategoriSelect).selectize({
valueField: 'kategori_diet_id',
labelField: 'nama_kategori_diet',
searchField: ['nama_kategori_diet', 'kategori_diet_id'],
create: false,
placeholder: "Kualifikasi Menu...",
maxItems: null,
load: function (query, callback) {
if (!query.length) return callback();
$.ajax({
url: '/dashboard/option/klasifikasi-menu',
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.nama_kategori_diet)}</div>
</div>`;
},
item: function (item, escape) {
return `<div>${escape(item.nama_kategori_diet)}</div>`;
}
}
});
}
if (tanggalSelect) {
$(tanggalSelect).selectize({
valueField: 'tanggal',
labelField: 'tgl',
create: true,
placeholder: "Masukkan Tanggal...",
});
}
formElement.querySelectorAll('.auto-expand').forEach(textarea => {
textarea.addEventListener('input', function () {
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
}
// Inisialisasi Selectize
function initSelectizeAll(context = document) {
$(context).find('.tags-menu').selectize(selectizeConfigTagsMenu);
$(context).find('.date-input').selectize(selectizeConfigDateInput);
}
// Destroy semua selectize sebelum clone
function destroySelectize(context) {
context.querySelectorAll('select').forEach(select => {
const instance = select.selectize;
if (instance) instance.destroy();
});
}
// Inisialisasi awal
document.querySelectorAll('.auto-expand').forEach(autoExpand);
initSelectizeAll();
// Tambah form-set
btnTambahForm.addEventListener('click', function () {
const lastFormSet = formSetsContainer.querySelector('.form-set:last-of-type');
// Destroy selectize sebelum clone
destroySelectize(lastFormSet);
const clone = lastFormSet.cloneNode(true);
// Bersihkan input dan textarea
clone.querySelectorAll('input, textarea').forEach(el => {
if (el.type === 'file') {
el.value = null;
} else {
el.value = '';
}
});
// Bersihkan select (hapus .selectize dan reset element <select>)
clone.querySelectorAll('select').forEach(select => {
const wrapper = select.parentElement.querySelector('.selectize-control');
if (wrapper) wrapper.remove();
select.innerHTML = ''; // Kosongkan option, bisa diisi ulang lewat AJAX
});
// Tampilkan tombol hapus
clone.querySelector('.btn-remove-form').classList.remove('d-none');
// Tambahkan ke DOM
formSetsContainer.appendChild(clone);
// Inisialisasi ulang textarea & Selectize untuk elemen baru
clone.querySelectorAll('.auto-expand').forEach(autoExpand);
initSelectizeAll();
});
// Hapus form-set
formSetsContainer.addEventListener('click', function (e) {
if (e.target.closest('.btn-remove-form')) {
const formSets = formSetsContainer.querySelectorAll('.form-set');
if (formSets.length > 1) {
e.target.closest('.form-set').remove();
} else {
alert('Minimal satu form harus ada.');
}
formElement.querySelectorAll('.money').forEach(input => {
input.addEventListener('input', function () {
let angka = this.value.replace(/[^0-9]/g, '');
this.value = formatAngka(angka);
});
});
const radioSomeday = formElement.querySelector(`input[value="Some Day"]`);
const radioMenuNormal = formElement.querySelector(`input[value="Menu Normal"]`);
const tanggalWrapper = formElement.querySelector('.date-input')?.closest('.col-md-12');
function toggleTanggalField() {
if (radioMenuNormal && radioMenuNormal.checked) {
tanggalWrapper?.classList.remove('d-none');
} else {
tanggalWrapper?.classList.add('d-none');
}
}
});
if (radioSomeday && radioMenuNormal) {
radioSomeday.addEventListener('change', toggleTanggalField);
radioMenuNormal.addEventListener('change', toggleTanggalField);
toggleTanggalField(); // jalankan di awal
}
}
// Jalankan saat halaman dimuat untuk form pertama
document.addEventListener('DOMContentLoaded', function () {
const firstForm = document.querySelector('.form-set');
initSelectize(firstForm);
const money = document.querySelectorAll('.money')
money.forEach(input => {
input.addEventListener('input', function(){
console.log();
let angka = this.value.replace(/[^0-9]/g, '');
this.value = formatAngka(angka)
})
})
});
// CONFIG SELECTIZE
// Fungsi untuk menambah form baru
function addFormMenu() {
const container = document.getElementById('form-sets-container');
const original = container.querySelector('.form-set');
const selectizeConfigTagsMenu = {
valueField: 'kategori_diet_id',
labelField: 'nama_kategori_diet',
searchField: ['nama_kategori_diet', 'kategori_diet_id'],
create: false,
placeholder: "Cari item kalibrasi...",
maxItems: null,
load: function(query, callback) {
if (!query.length) return callback();
$.ajax({
url: '/dashboard/option/klasifikasi-menu',
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.nama_kategori_diet)}
</div>
</div>`;
},
item: function(item, escape) {
return `<div>${escape(item.nama_kategori_diet)}</div>`;
const html = original.outerHTML
.replace(/\[0\]/g, `[${countForm}]`)
.replace(/name="jenis_customer"/g, `name="jenis_customer_${countForm}"`)
.replace(/id="radio_karyawan"/g, `id="radio_karyawan_${countForm}"`)
.replace(/id="radio_kp"/g, `id="radio_kp_${countForm}"`)
.replace(/for="radio_karyawan"/g, `for="radio_karyawan_${countForm}"`)
.replace(/for="radio_kp"/g, `for="radio_kp_${countForm}"`);
const wrapper = document.createElement('div');
wrapper.innerHTML = html.trim();
const newForm = wrapper.firstChild;
// Kosongkan semua input
newForm.querySelectorAll('input, textarea').forEach(el => {
if (el.type === 'file') el.value = null;
else if (el.type === 'radio' || el.type === 'checkbox') el.checked = false;
else el.value = '';
});
// Hapus Selectize wrapper jika ada
newForm.querySelectorAll('select').forEach(select => {
const wrapper = select.nextElementSibling;
if (wrapper?.classList.contains('selectize-control')) wrapper.remove();
console.log(select);
select.value = '';
if (select.multiple) {
// Untuk multiple select, pastikan semua opsi tidak terseleksi
Array.from(select.options).forEach(option => option.selected = false);
}
});
container.appendChild(newForm);
initSelectize(newForm);
countForm++;
}
// Hapus form-set (kecuali jika hanya 1)
document.addEventListener('click', function (e) {
if (e.target.closest('.btn-remove-form')) {
const targetForm = e.target.closest('.form-set');
const total = document.querySelectorAll('.form-set').length;
if (total > 1) {
targetForm.remove();
} else {
alert('Minimal satu form harus ada.');
}
}
};
});
const selectizeConfigDateInput = {
valueField: 'tgl',
labelField: 'tgl',
searchField: 'tgl',
create: true,
placeholder: "Masukkan Tanggal...",
};
function formatAngka(angka) {
return angka.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
}
document.getElementById('formMasterMenu').addEventListener('submit', function(e){
e.preventDefault();
const allFormSets = document.querySelectorAll('.form-set');
for (let i = 0; i < allFormSets.length; i++) {
const checkSiang = allFormSets[i].querySelector(`input[name="data[${i}][apakah_menu_siang]"]`);
const checkSore = allFormSets[i].querySelector(`input[name="data[${i}][apakah_menu_sore]"]`);
if (!checkSiang.checked && !checkSore.checked) {
e.preventDefault();
alert(`Form ke-${i + 1}: Pilih minimal Siang atau Sore`);
return;
}
}
const form = this;
const actionUrl = form.getAttribute('action');
const formData = new FormData(form);
fetch(actionUrl, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
},
body: formData
}).then(async (res) => {
const data = await res.json();
if (data.status) {
const handler = function () {
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: data.message,
timer: 2000,
showConfirmButton: false,
backdrop: true,
});
datatableMasterMenu.bootstrapTable('refresh');
modalAddMenu.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
};
modalAddMenu.addEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
bootstrap.Modal.getInstance(modalAddMenu).hide(); // ✅ pakai instance
document.querySelectorAll('.form-set').forEach((formSet, index) => {
formSet.querySelectorAll('input, textarea, select').forEach(el => {
if (el.type === 'file') {
el.value = null;
} else if (el.type === 'checkbox' || el.type === 'radio') {
el.checked = false;
} else {
el.value = '';
}
// Reset Selectize jika ada
if (el.classList.contains('selectized')) {
const selectize = el.selectize;
if (selectize) {
selectize.clear();
}
}
});
});
} else {
throw new Error(data.message || 'Terjadi kesalahan saat mengubah status.');
}
}).catch(err => {
console.error(err);
Swal.fire({
icon: 'error',
title: 'Gagal',
text: err.message || 'Terjadi kesalahan pada server.',
});
});
})
function deleteMasterMenu(e){
let id = $(e).data('master_menu_id')
Swal.fire({
title: "Apakah kamu yakin ingin menghapus data ini?",
text : $(e).data('nama'),
icon: "warning",
showCancelButton: true,
backdrop: true,
}).then((result) => {
if(result.isConfirmed){
fetch(`/dashboard/menu/${id}`, {
method:'DELETE',
headers: {
"X-CSRF-TOKEN": document.querySelector('input[name="_token"]').value,
"Content-Type": "application/json"
}
}).then((response) => {
if(!response.ok){
throw new Error("Network response was not ok");
}
return response.json();
})
.then((data) => {
if(data.status){
Swal.fire({
title: "Success",
text: "Data berhasil dihapus",
icon:"success",
showConfirmButton: false,
timer: 1000
}).then(() => {
datatableMasterMenu.bootstrapTable("refresh")
})
}else{
Swal.fire({
title: "Error!",
text: data.message || "Failed to delete Item.",
icon: "error"
});
}
})
.catch(error => {
Swal.fire({
title: "Error!",
text: "Something went wrong. Please try again later.",
icon: "error"
});
});
}
})
}

View File

@ -1,6 +1,6 @@
datatableMasterMenu.bootstrapTable({
url: "/",
url: "/dashboard/datatable/menu",
showColumns: true,
showColumnsToggleAll: true,
showRefresh: true,
@ -13,7 +13,7 @@
pageSize: 10,
pageList: [10, 20, 30, 40, 50, 100, 200],
cookie: true,
cookieIdTable: "table_rma_ssc_id",
cookieIdTable: "datatableMasterMenu",
icons: {
refresh: "fas fa-sync-alt", // atau ganti ke icon lain
columns: "fas fa-th-large"
@ -22,18 +22,96 @@
columns: [
{
title: "Action",
field: 'master_menu_id',
formatter: function(value, row) {
let buttons = ''
buttons += `
<button class="btn btn-sm btn-primary me-2" onclick="editMasterMenu(this)" data-master_menu_id="${row.master_menu_id}">
<i class="fa-solid fa-pencil"></i>
</button>
`
buttons += `
<button class="btn btn-sm btn-danger me-2" onclick="deleteMasterMenu(this)" data-master_menu_id="${row.master_menu_id}" data-nama="${row?.nama_menu}">
<i class="fa-solid fa-trash"></i>
</button>
`
return `
<div class="d-flex space-x">
${buttons}
</div>
`;
},
width: 120
},
{
title: "Nama Menu",
title:"Nama Menu",
field:"nama_menu",
width: 300
},
{
title: "Jenis Menu",
title:"Harga",
field:"master_menu_id",
formatter: function(value, row) {
return `<ul style="white-space: nowrap;">
<li>Public : <strong>Rp ${parseInt(row.harga_public).toLocaleString('id-ID')}</strong></li>
<li>Keluarga Pasien/Pasien : <strong>Rp ${parseInt(row.harga_keluarga_pasien).toLocaleString('id-ID')}</strong></li>
<li>Karyawan : <strong>Rp ${parseInt(row.harga_karyawan).toLocaleString('id-ID')}</strong></li>
</ul>`
},
width: 200
},
{
title: "Harga",
title:"Kategori",
field:"jenis_menu",
},
{
title: "Deskripsi",
title: "Kategori Menu",
field: "master_menu_id",
formatter: function (value, row) {
if (row?.apakah_someday) {
return `<span class="badge bg-warning text-dark">Someday</span>`;
}
return `<span class="badge bg-success text-dark">Menu Normal</span>`;
}
},
{
title: "Waktu Makan",
field: "master_menu_id",
formatter: function (value, row) {
if (row?.apakah_menu_siang && row?.apakah_menu_sore) {
return `Makan Siang & Sore`;
} else if (row?.apakah_menu_siang) {
return `Makan Siang`;
} else if (row?.apakah_menu_sore) {
return `Makan Sore`;
} else {
return `-`;
}
},
width: 250
},
{
title:"Tanggal Tersedia",
field:"master_menu_id",
formatter: function(value, row){
if(row.apakah_someday) return 'Senin - Minggu'
let tglAvlb = '';
tglAvlb = row?.tgl ? row?.tgl.map(item => item?.tgl_harian).join(', ') : '-';
return tglAvlb;
}
},
{
title:"Deskripsi",
field:"deskripsi",
},
{
title:"Klasifikasi Menu",
field:"master_menu_id",
formatter: function(value, row){
let km = '';
km = row?.kategoriDiet ? row?.kategoriDiet.map(item => item?.nama_kategori_diet).join(', ') : '-';
return km;
}
},
],

View File

@ -4,3 +4,9 @@ const modalActionOrder = document.getElementById("modalActionOrder")
const formActionOrder = $("#formActionOrder")
const containerCancel = document.getElementById("note_dibatalkan")
const noteCancelTextArea = document.getElementById("textarea_note_dibatalkan")
const modalActionApproveBillingnOrder = document.getElementById("modalActionApproveBillingOrder")
const formActionApproveBillingOrder = $("#formActionApproveBillingOrder")
const modalActionProgressOrder = document.getElementById('modalActionProgressOrder')
const formActionProgressOrder = $("#formActionProgressOrder")

View File

@ -83,3 +83,62 @@ noteCancelTextArea.addEventListener('input', function () {
this.style.height = 'auto'; // Reset height dulu
this.style.height = this.scrollHeight + 'px'; // Set height sesuai isi
});
function AdminApproved(e){
const data = $(e).data()
new bootstrap.Modal(modalActionApproveBillingnOrder).show();
$("#confirmActionApproveBillingOrder").text('Pembayaran Via Billing '+ data.nama_pemesan + ' / ' + data.no_order)
formActionApproveBillingOrder.attr(`action`, `/dashboard/pending/action-billing/${data.order_id}`)
}
document.getElementById('formActionApproveBillingOrder').addEventListener('submit', function (e) {
e.preventDefault();
const form = this;
const actionUrl = form.getAttribute('action');
const formData = new FormData(form);
fetch(actionUrl, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
},
body: formData
}).then(async (res) => {
const data = await res.json();
if (res.status) {
const handler = function () {
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: data.message || 'Status berhasil diubah!',
timer: 2000,
showConfirmButton: false,
backdrop: true,
});
datatablePending.bootstrapTable('refresh');
modalActionApproveBillingnOrder.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
};
modalActionApproveBillingnOrder.addEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
bootstrap.Modal.getInstance(modalActionApproveBillingnOrder).hide(); // ✅ pakai instance
} else {
throw new Error(data.message || 'Terjadi kesalahan saat mengubah status.');
}
}).catch(err => {
console.error(err);
Swal.fire({
icon: 'error',
title: 'Gagal',
text: err.message || 'Terjadi kesalahan pada server.',
});
});
});
function approveProgress(e){
new bootstrap.Modal(modalActionProgressOrder).show();
}

View File

@ -32,7 +32,6 @@
<i class="fa fa-check me-1"></i>
</button>
`
}
if(row?.status_order !== "Lunas"){
buttons += `
@ -42,6 +41,15 @@
</button>
`
}
if(row?.status_order === "Menunggu Konfirmasi Pembayaran Via Billing"){
buttons += `
<button class="btn btn-sm btn-info me-2" onclick="AdminApproved(this)"
data-order_id="${row.order_id}" data-nama_pemesan="${row?.nama_pemesan}" data-no_order="${row?.no_order}" data-jenis_customer="${row?.jenis_customer}">
<i class="fa-solid fa-person-circle-check"></i>
</button>
`
}
if(row?.status_order === "Lunas"){
buttons += `
<button class="btn btn-sm btn-warning text-dark" onclick="approveProgress('${row.order_id}')">
@ -60,7 +68,7 @@
{
title: "No.Order",
field:'no_order',
field: 'no_order',
sortable: true,
},
{
@ -89,6 +97,10 @@
`;
}
},
{
title: "Status Pesanan",
sortable: true,
},
{
title: "Pemesan",
field:'nama_pemesan',

View File

@ -10,7 +10,7 @@
</div>
<!-- Modal Form -->
<form enctype="multipart/form-data" method="POST" id="formMasterMenu">
<form action="/dashboard/menu" enctype="multipart/form-data" method="POST" id="formMasterMenu">
@csrf
<div class="modal-body">
<div class="container">
@ -22,7 +22,7 @@
<i class="bx bx-trash"></i>
</button>
<div class="row g-3">
<div class="row g-3 mt-3">
<div class="col-md-12">
<div class="form-floating">
<input type="text" class="form-control" name="data[0][nama]" placeholder="Nama Menu" required>
@ -32,28 +32,28 @@
<div class="col-md-4">
<div class="form-floating">
<input type="text" class="form-control" name="data[0][harga_public]" placeholder="Harga" required>
<input type="text" class="form-control money" name="data[0][harga_public]" placeholder="Harga" required>
<label>Harga Publik</label>
</div>
</div>
<div class="col-md-4">
<div class="form-floating">
<input type="number" step="0.01" class="form-control" name="data[0][harga_karyawan]" placeholder="Harga" required>
<input type="text" step="0.01" class="form-control money" name="data[0][harga_karyawan]" placeholder="Harga" required>
<label>Harga Karyawan</label>
</div>
</div>
<div class="col-md-4">
<div class="form-floating">
<input type="number" step="0.01" class="form-control" name="data[0][harga_keluarga_pasien]" placeholder="Harga" required>
<input type="text" step="0.01" class="form-control money" name="data[0][harga_keluarga_pasien]" placeholder="Harga" required>
<label>Harga Keluarga Pasien / Pasien</label>
</div>
</div>
<div class="col-md-12">
<div class="form-floating">
<select class="form-select" name="data[0][jenis_menu]" required>
<select class="form-select" name="data[0][jenis_makanan]" required>
<option selected disabled>Pilih kategori</option>
<option value="Snack">Snack</option>
<option value="Makanan">Makanan</option>
@ -79,34 +79,49 @@
<div class="col-md-12">
<label for="tags" class="form-label">Tag Menu</label>
<select class="tags-menu" multiple name="kategori_diet_id[]"></select>
<select class="tags-menu" multiple name="data[0][kategori_diet_id][]"></select>
</div>
<div class="col-md-12">
<label for="exampleInputEmail1" class="form-label">Jenis Menu</label>
<div class="col-md-6">
<label for="exampleInputEmail1" class="form-label">Kategori Menu</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_karyawan" value="Karyawan RSAB Harapan Kita" required>
<input class="form-check-input" type="radio" name="data[0][kategori_menu]" id="radio_karyawan" value="Some Day" required>
<label class="form-check-label" for="radio_karyawan" >
Some Day
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_kp" value="Keluarga Pasien / Penunggu Pasien" required>
<label class="form-check-label" for="radio_kp">
<input class="form-check-input" type="radio" name="data[0][kategori_menu]" id="" value="Menu Normal" required>
<label class="form-check-label" for="">
Menu Normal
</label>
</div>
</div>
<div class="col-md-12">
<div class="col-md-6">
<label for="exampleInputEmail1" class="form-label">Waktu Menu Tersedia</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="data[0][apakah_menu_siang]" id="checkSiang" value="iya">
<label class="form-check-label" for="checkSiang" >
Siang
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="data[0][apakah_menu_sore]" id="checkSore" value="iya">
<label class="form-check-label" for="checkSore">
Sore
</label>
</div>
</div>
<div class="col-md-12 d-none">
<label for="tags" class="form-label">Tanggal Menu Tersedia</label>
<select class="date-input" multiple name="tanggal[]"></select>
<select class="date-input" multiple name="data[0][tanggal][]"></select>
</div>
</div>
</div>
</div>
<!-- Tombol tambah form-set -->
<button type="button" class="btn btn-outline-primary btn-sm mt-2" id="btnTambahForm">
<button type="button" class="btn btn-outline-primary btn-sm mt-2" onclick="addFormMenu()">
+ Tambah Data
</button>
</div>

View File

@ -19,6 +19,8 @@
</div>
@include('dashboard.pesanan.pending.modal.action')
@include('dashboard.pesanan.pending.modal.confirmBilling')
@include('dashboard.pesanan.pending.modal.actionProgressPesanan')
<script src="{{ ver('/js/pesanan_pending/_init.js') }}"></script>
<script src="{{ ver('/js/pesanan_pending/dt.js') }}"></script>

View File

@ -0,0 +1,37 @@
<!-- Modal -->
<div class="modal fade" id="modalActionProgressOrder" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h5 class="modal-title fs-5">Aksi Progress Pesanan</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal Form -->
<form method="POST" id="formActionProgressOrder">
@csrf
@method('put')
<div class="modal-body ">
<div class="container">
<div class="row mt-3">
<div class="col-md-4 text-center mb-3 mb-md-0">
<img alt="Foto Menu" id="cathering_order_photo" lass="img-fluid rounded shadow" style="max-height: 170px; width: auto;">
</div>
<div class="col-md-8">
</div>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="submit" class="btn btn-primary">Setujui</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<!-- Modal -->
<div class="modal fade" id="modalActionApproveBillingOrder" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h5 class="modal-title fs-5">Aksi </h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal Form -->
<form method="POST" id="formActionApproveBillingOrder">
@csrf
@method('put')
<div class="modal-body ">
Apakah kamu yakin melakukan persetujuan pada order ini ? <strong id="confirmActionApproveBillingOrder"></strong>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<button type="submit" class="btn btn-primary">Setujui</button>
</div>
</form>
</div>
</div>
</div>

View File

@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Route;
// });
Route::get('/login', [AuthController::class, 'index'])->name('login');
Route::post('/login', [AuthController::class, 'authanticate']);
Route::resource('/dashboard/menu', MenuController::class);
Route::group(['middleware' => ['auth']], function(){
Route::group(['prefix' => 'dashboard'], function(){
@ -30,11 +30,14 @@ Route::group(['middleware' => ['auth']], function(){
Route::resource('/karbohidrat', KarbohidratController::class);
Route::get('/datatable/karbohidrat', [KarbohidratController::class, 'datatable']);
Route::resource('/menu', MenuController::class);
Route::get('/datatable/menu', [MenuController::class, 'datatable']);
Route::get('/pending', [PesananController::class, 'index']);
Route::get('datatable/pending', [PesananController::class, 'getDataPending']);
Route::put('/pending/action/{order_id}', [PesananController::class, 'actionOrder']);
Route::put('/pending/action-billing/{order_id}', [PesananController::class, 'actionOrderViaBilling']);
Route::get('/action/progress-order/{order_id}', [PesananController::class, 'getDataOrderDetail']);
});