on progress
This commit is contained in:
parent
80548af3a7
commit
b9b22a2848
@ -107,7 +107,8 @@ class CustomerController extends Controller
|
||||
|
||||
|
||||
private static function dataPaketMenuOrder($search = null, $perPage){
|
||||
$query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')->where('mpn.statusenabled', true);
|
||||
$query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')
|
||||
->where('mpn.statusenabled', true);
|
||||
|
||||
if(!empty($search)){
|
||||
$query->where('mpn.nama_paket', 'ILIKE', '%' . $search . '%');
|
||||
@ -121,11 +122,13 @@ class CustomerController extends Controller
|
||||
'mpn.harga_karyawan',
|
||||
'mpn.harga_keluarga_pasien',
|
||||
'mpn.deskripsi',
|
||||
'mpn.status'
|
||||
'mpn.status',
|
||||
'dmph.detail_menu_paket_harian_id',
|
||||
'dmph.tgl_harian'
|
||||
)->paginate($perPage);
|
||||
|
||||
$paketMenuIds = collect($paginated->items())->pluck('master_paket_menu_id')->toArray();
|
||||
|
||||
dd($paketMenuIds);
|
||||
$klasifikasi = DB::connection('dbOrderGizi')
|
||||
->table('public.klasifikasi_menu_diet as kmd')
|
||||
->join('public.kategori_diet as kd', 'kd.kategori_diet_id', '=', 'kmd.kategori_diet_id')
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderDetail;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@ -22,8 +23,45 @@ class PesananController extends Controller
|
||||
|
||||
|
||||
public function getDataPending(){
|
||||
$data = Order::where('statusenabled', true)->get();
|
||||
return $data;
|
||||
$orders = DB::connection('dbOrderGizi')->table('public.order as o')
|
||||
->leftJoin('public.order_detail as od', 'od.order_id', '=', 'o.order_id')
|
||||
->where('o.statusenabled', true)
|
||||
->select(
|
||||
'o.order_id',
|
||||
'o.no_order',
|
||||
'o.nama_pemesan',
|
||||
'o.jenis_customer',
|
||||
'o.total_harga',
|
||||
'o.status_order',
|
||||
'o.bukti_pembayaran',
|
||||
'o.note_dibatalkan',
|
||||
'od.status_order as detail_status_order'
|
||||
)->get()->groupBy('order_id');
|
||||
|
||||
$grouped = $orders->map(function($items){
|
||||
$first = $items->first();
|
||||
$totalDetail = $items->count();
|
||||
$selesaiDetail = $items->where('detail_status_order', 'Selesai')->count();
|
||||
$progress = $totalDetail > 0 ? round(($selesaiDetail / $totalDetail) * 100) : 0;
|
||||
return [
|
||||
'order_id' => $first->order_id,
|
||||
'no_order' => $first->no_order,
|
||||
'nama_pemesan' => $first->nama_pemesan,
|
||||
'jenis_customer' => $first->jenis_customer,
|
||||
'total_harga' => $first->total_harga,
|
||||
'status_order' => $first->status_order,
|
||||
'bukti_pembayaran' => $first->bukti_pembayaran,
|
||||
'progress' => $progress,
|
||||
'total_detail' => $totalDetail,
|
||||
'selesai_detail' => $selesaiDetail,
|
||||
'note_dibatalkan' => $first->note_dibatalkan,
|
||||
];
|
||||
})->values();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'rows' => $grouped->values(),
|
||||
'total' => $grouped->count()
|
||||
]);
|
||||
}
|
||||
|
||||
public function actionOrder(Request $request, string $order_id){
|
||||
@ -88,6 +126,18 @@ class PesananController extends Controller
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
public function updateDetailStatusOrder($order_detail_id){
|
||||
$orderDetail = OrderDetail::where('order_detail_id', $order_detail_id)->first();
|
||||
$payload = [
|
||||
'status_order' => 'Selesai',
|
||||
'modified_at' => Carbon::now(),
|
||||
];
|
||||
$orderDetail->update($payload);
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
BIN
public/gambar/jbFPdYgWyiUtmMB.png
Normal file
BIN
public/gambar/jbFPdYgWyiUtmMB.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 320 KiB |
@ -139,6 +139,7 @@ document.getElementById('formActionApproveBillingOrder').addEventListener('submi
|
||||
});
|
||||
|
||||
|
||||
function approveProgress(e){
|
||||
function approveProgress(order_id){
|
||||
new bootstrap.Modal(modalActionProgressOrder).show();
|
||||
fetchDetailOrder(order_id)
|
||||
}
|
||||
|
||||
144
public/js/pesanan_pending/action_progres_order.js
Normal file
144
public/js/pesanan_pending/action_progres_order.js
Normal file
@ -0,0 +1,144 @@
|
||||
function fetchDetailOrder(order_id){
|
||||
fetch(`/dashboard/pending/action-progress-order/${order_id}`)
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
const data = res;
|
||||
document.getElementById('pesanan_container').innerHTML =''
|
||||
// Generate HTML untuk order_detail
|
||||
const detailHTML = (data?.order_detail || []).map(detail => {
|
||||
return `
|
||||
<div class="col-md-12 mb-3">
|
||||
<div class="card shadow-sm">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-5 d-flex align-items-center p-2">
|
||||
<img src="/gambar/${detail?.menu?.foto || 'default.jpg'}" alt="Foto Menu" class="img-fluid rounded shadow" style="max-height: 120px; width: auto;">
|
||||
</div>
|
||||
<div class="col-md-5 p-2">
|
||||
<p class="mb-1">Nama Menu: <strong>${detail?.menu?.nama_menu || '-'}</strong></p>
|
||||
<p class="mb-1">Jumlah: <span>${detail?.jumlah || 0}</span></p>
|
||||
<p class="mb-1">Tanggal Pesan: <span>${detail?.tgl_antar || 0}</span></p>
|
||||
<p class="mb-1">Harga: <strong>Rp ${parseInt(detail?.harga_satuan || 0).toLocaleString('id-ID')}</strong></p>
|
||||
<p class="mb-1">Status Pesanan:
|
||||
<span class="badge text-dark ${detail?.status_order === 'Selesai' ? 'bg-success' : 'bg-warning'}"
|
||||
id="status_badge_${detail.order_detail_id}">
|
||||
${detail?.status_order}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="form-check form-switch mt-2">
|
||||
<input class="form-check-input status-switch" type="checkbox"
|
||||
id="switch_status_${detail.order_detail_id}"
|
||||
data-id="${detail.order_detail_id}"
|
||||
${detail.status_order === 'Selesai' ? 'checked' : ''} ${detail.status_order === 'Selesai' ? 'disabled' : ''}>
|
||||
<label class="form-check-label " for="switch_status_${detail.order_detail_id}">
|
||||
${detail.status_order === 'Selesai' ? `Selesai` : 'Tandai sebagai Selesai'}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
const html = `
|
||||
<div class="row mt-3">
|
||||
<!-- Bagian Kiri: Gambar Bukti Pembayaran -->
|
||||
<div class="col-md-4 text-center mb-3 mb-md-0">
|
||||
<img src="/storage/${data.bukti_pembayaran || 'gambar/default.jpg'}" alt="Bukti Pembayaran" class="img-fluid rounded shadow" style="max-height: 170px; width: auto;">
|
||||
</div>
|
||||
|
||||
<!-- Bagian Kanan: Informasi Pemesan -->
|
||||
<div class="col-md-8">
|
||||
<div class="mb-2">
|
||||
<h5 class="mb-0">Nama Pemesan: <span class="text-primary" id="nama_pemesan">${data.nama_pemesan}</span></h5>
|
||||
<small class="text-muted">Jenis Customer: <span id="jenis_customer">${data.jenis_customer}</span></small>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<p class="mb-1">No Order: <strong id="no_order">${data.no_order}</strong></p>
|
||||
<p class="mb-1">Type Pembayaran: <strong id="no_order">${data.cara_pembayaran}</strong></p>
|
||||
<p class="mb-1">Tanggal Pembayaran: <span id="tgl_pembayaran">${data.tgl_pembayaran || '-'}</span></p>
|
||||
<p class="mb-1">Total Harga: <strong id="total_harga">Rp ${parseInt(data.total_harga).toLocaleString('id-ID')}</strong></p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<label class="form-label">Status Saat Ini:</label>
|
||||
<span class="badge text-dark ${data?.status_order === 'Lunas' ? 'bg-success' : 'bg-warning'}" id="status_order">${data.status_order}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<div class="row">
|
||||
${detailHTML}
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('pesanan_container').innerHTML = html;
|
||||
|
||||
|
||||
document.querySelectorAll('.status-switch').forEach(el => {
|
||||
el.addEventListener('change', function () {
|
||||
const id = this.dataset.id;
|
||||
const isChecked = this.checked;
|
||||
const newStatus = isChecked ? 'Selesai' : 'Pending';
|
||||
|
||||
// Update badge UI
|
||||
const badge = document.getElementById(`status_badge_${id}`);
|
||||
if (badge) {
|
||||
badge.innerText = newStatus;
|
||||
badge.className = `badge text-dark ${isChecked ? 'bg-success' : 'bg-warning'}`;
|
||||
}
|
||||
|
||||
// Kirim ke backend
|
||||
fetch(`/dashboard/pending/update-detail-status/${id}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value
|
||||
},
|
||||
body: JSON.stringify({ status_order: newStatus })
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
el.disabled = true;
|
||||
datatablePending.bootstrapTable('refresh')
|
||||
showToast('Status berhasil diperbarui!');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Gagal update status:', err);
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
document.getElementById('pesanan_container').innerHTML = '<p class="text-danger">Terjadi kesalahan saat memuat data.</p>';
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Tambah listener untuk semua switch
|
||||
|
||||
function showToast(message, isError = false) {
|
||||
const toastId = `toast_${Date.now()}`;
|
||||
const toastHTML = `
|
||||
<div id="${toastId}" class="toast align-items-center text-white ${isError ? 'bg-danger' : 'bg-success'} border-0 show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">${message}</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const container = document.getElementById('toastContainer');
|
||||
container.insertAdjacentHTML('beforeend', toastHTML);
|
||||
|
||||
// Hapus toast setelah 3 detik
|
||||
setTimeout(() => {
|
||||
const toast = document.getElementById(toastId);
|
||||
if (toast) toast.remove();
|
||||
}, 3000);
|
||||
}
|
||||
@ -83,7 +83,7 @@
|
||||
} else if (status === "Menunggu Konfirmasi Pembayaran") {
|
||||
badgeClass = 'bg-primary';
|
||||
} else if (status === "Lunas" || status === "Sudah Bayar") {
|
||||
badgeClass = 'bg-success';
|
||||
badgeClass = 'bg-success text-dark';
|
||||
} else if(status === "Dibatalkan"){
|
||||
badgeClass = 'bg-danger';
|
||||
}
|
||||
@ -99,6 +99,24 @@
|
||||
},
|
||||
{
|
||||
title: "Status Pesanan",
|
||||
formatter: function(value, row) {
|
||||
const progress = parseInt(row.progress) || 0;
|
||||
const total = row.total_detail || 0;
|
||||
const selesai = row.selesai_detail || 0;
|
||||
|
||||
return `
|
||||
<div class="text-center">
|
||||
<div class="progress" style="height: 18px;">
|
||||
<div class="progress-bar bg-success" role="progressbar"
|
||||
style="width: ${progress}%;"
|
||||
aria-valuenow="${progress}" aria-valuemin="0" aria-valuemax="100">
|
||||
${progress}%
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">${selesai} / ${total} selesai</small>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
|
||||
@ -104,6 +104,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Overlay -->
|
||||
<div id="toastContainer" class="position-fixed top-0 end-0 p-3" style="z-index: 9999;"></div>
|
||||
<div class="layout-overlay layout-menu-toggle"></div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
@ -25,4 +25,5 @@
|
||||
<script src="{{ ver('/js/pesanan_pending/_init.js') }}"></script>
|
||||
<script src="{{ ver('/js/pesanan_pending/dt.js') }}"></script>
|
||||
<script src="{{ ver('/js/pesanan_pending/action.js') }}"></script>
|
||||
<script src="{{ ver('/js/pesanan_pending/action_progres_order.js') }}"></script>
|
||||
@endsection
|
||||
|
||||
@ -13,22 +13,17 @@
|
||||
<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>
|
||||
<div class="modal-body">
|
||||
<div class="container" id="pesanan_container"></div>
|
||||
<!-- Tempatkan ini di layout HTML -->
|
||||
|
||||
|
||||
</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>
|
||||
|
||||
|
||||
@ -37,7 +37,8 @@ Route::group(['middleware' => ['auth']], function(){
|
||||
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']);
|
||||
Route::get('/pending/action-progress-order/{order_id}', [PesananController::class, 'getDataOrderDetail']);
|
||||
Route::post('/pending/update-detail-status/{order_id}', [PesananController::class, 'updateDetailStatusOrder']);
|
||||
|
||||
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user