order_gizi/app/Http/Controllers/PesananController.php
2025-08-12 17:24:34 +07:00

663 lines
25 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Mail\NotifikasiKonfirmasiPembayaran;
use App\Models\Order;
use App\Models\OrderDetail;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class PesananController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$payload = [
'title' => 'Pesanan Pending'
];
return view('dashboard.pesanan.pending.index', $payload);
}
public function getDataPending(){
$tanggal = request('tanggal');
if(!empty($tanggal)){
$tanggalFormatted = collect($tanggal)->map(function ($tgl){
return Carbon::parse($tgl)->toDateString();
})->toArray();
}else{
$tanggalFormatted = [Carbon::now()->toDateString()];
}
$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)
->whereRaw(
"DATE(o.entry_at) IN (" . implode(',', array_fill(0, count($tanggalFormatted), '?')) . ")",
$tanggalFormatted
)
->whereIn('o.status_order', ['Menunggu Konfirmasi Pembayaran', 'Menunggu Konfirmasi Pembayaran Via Billing'])
->select(
'o.order_id',
'o.entry_at',
'o.no_order',
'o.nama_pemesan',
'o.jenis_customer',
'o.cara_pembayaran',
'o.status_order',
'o.total_harga',
'o.bukti_pembayaran',
'o.note_dibatalkan',
'o.medical_record',
'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,
'entry_at' => $first->entry_at,
'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,
'cara_pembayaran' => $first->cara_pembayaran,
'bukti_pembayaran' => $first->bukti_pembayaran,
'medical_record' => $first->medical_record,
'progress' => $progress,
'total_detail' => $totalDetail,
'selesai_detail' => $selesaiDetail,
'note_dibatalkan' => $first->note_dibatalkan,
];
})
->filter(function($item){
return $item['total_detail'] > 0 && $item['total_detail'] != $item['selesai_detail'];
})->values();
return response()->json([
'status' => true,
'rows' => $grouped->values(),
'total' => $grouped->count()
]);
}
public function actionOrder(Request $request, string $order_id){
DB::connection('dbOrderGizi')->beginTransaction();
try {
$order = Order::where('order_id', $order_id)->first();
$action = $request->query('action');
$payload = [
'pegawai_id_confirm_order' => auth()->user()->id,
'pegawai_name_confirm_order' => auth()->user()->full_name,
'pegawai_at_confirm_order' => Carbon::now(),
'status_order' => $action ?? 'Dibatalkan',
];
if(!$action){
$payload['note_dibatalkan'] = request('note_dibatalkan');
}
$order->update($payload);
if($order->email){
Mail::to($order->email)->queue(new NotifikasiKonfirmasiPembayaran($order->nama_pemesan, $order->no_order, $order->total_harga));
}
DB::connection('dbOrderGizi')->commit();
return response()->json([
'status' => true,
'message' => $action ? 'Konfirmasi Order Gizi telah disetujui!' : 'Konfirmasi Order Gizi telah dibatalkan'
]);
} catch (\Throwable $th) {
DB::connection('dbOrderGizi')->rollBack();
return response()->json([
'status' => false,
'message' => 'Gagal melakukan Konfirmasi Order Gizi'
]);
//throw $th;
}
}
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);
if($order->email){
Mail::to($order->email)->queue(new NotifikasiKonfirmasiPembayaran($order->nama_pemesan, $order->no_order, $order->total_harga));
}
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);
}
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,
]);
}
public function indexSelesai()
{
$payload = [
'title' => 'Pesanan Selesai'
];
return view('dashboard.pesanan.selesai.index', $payload);
}
public function getDataSelesai(){
$tanggal = request('tanggal');
if(!empty($tanggal)){
$tanggalFormatted = collect($tanggal)->map(function ($tgl){
return Carbon::parse($tgl)->toDateString();
})->toArray();
}else{
$tanggalFormatted = [Carbon::now()->toDateString()];
}
$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])
->whereRaw(
"DATE(o.entry_at) IN (" . implode(',', array_fill(0, count($tanggalFormatted), '?')) . ")",
$tanggalFormatted
)
->select(
'o.order_id',
'o.entry_at',
'o.no_order',
'o.nama_pemesan',
'o.jenis_customer',
'o.total_harga',
'o.cara_pembayaran',
'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,
'entry_at' => $first->entry_at,
'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,
'cara_pembayaran' => $first->cara_pembayaran,
'progress' => $progress,
'total_detail' => $totalDetail,
'selesai_detail' => $selesaiDetail,
'note_dibatalkan' => $first->note_dibatalkan,
];
})
->filter(function($item){
return $item['total_detail'] > 0 && $item['total_detail'] === $item['selesai_detail'];
})
->values();
return response()->json([
'status' => true,
'rows' => $grouped->values(),
'total' => $grouped->count()
]);
}
public function pekerjaan(){
$data = [
'title' => 'List Pekerjaan Order Gizi'
];
return view('dashboard.pesanan.pekerjaan.index', $data);
}
public function getPekerjaan(){
$data = OrderDetail::with(['menu', 'paketMenu', 'order', 'karbohidrat'])->whereHas('order', function($q){
$q->where('status_order', 'Lunas');
});
$tanggal = request('tanggal');
if(!empty($tanggal)){
$flattened = is_array($tanggal[0]) ? Arr::flatten($tanggal) : $tanggal;
$data->whereIn('tgl_antar', $flattened);
}else{
$now = Carbon::now()->format('Y-m-d');
$data->where('tgl_antar', $now);
}
$data = $data->get();
return response()->json([
'rows' => $data->values(),
'total' => $data->count()
]);
}
public function getPekerjaanDetail($order_detail_id){
$data = OrderDetail::where('order_detail_id', $order_detail_id)->with(['order', 'menu', 'paketMenu'])->first();
return response()->json([
'status' => true,
'data' => $data
]);
}
public function exportPekerjaan(){
$startDate = request('start_date');
$endDate = request('end_date');
$now = Carbon::now()->format('Y-m-d H-i');
$orderDetail = OrderDetail::with(['menu', 'paketMenu', 'order', 'karbohidrat'])->whereHas('order', function($q){
$q->where('status_order', 'Lunas');
})->whereBetween('tgl_antar', [$startDate, $endDate])->get();
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$data = [
'pekerjaan' => $orderDetail,
'waktu_cetak' => $waktu_cetak,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.pekerjaan.pdf', $data);
return $pdf->stream("daftar-pesanan-{$now}.pdf");
}
public function exportPending(){
$startDate = Carbon::parse(request('start_date'))->startOfDay();
$endDate = Carbon::parse(request('end_date'))->endOfDay();
$order = Order::where('statusenabled', true)
->whereBetween('entry_at', [$startDate, $endDate])
->with('orderDetail')
->whereIn('status_order', ['Menunggu Konfirmasi Pembayaran', 'Menunggu Konfirmasi Pembayaran Via Billing'])
->get();
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$data = [
'laporan' => 'LAPORAN KONFIRMASI PESANAN',
'waktu_cetak' => $waktu_cetak,
'orders' => $order,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.pending.pdf', $data);
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
public function exportSelesai(){
$startDate = Carbon::parse(request('start_date'))->startOfDay();
$endDate = Carbon::parse(request('end_date'))->endOfDay();
$order = Order::where('statusenabled', true)
->whereBetween('entry_at', [$startDate, $endDate])
->with('orderDetail')
->whereHas('orderDetail') // hanya order yang punya detail
->whereDoesntHave('orderDetail', function($q) {
$q->where('status_order', '!=', 'Selesai');
})
->get();
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$data = [
'waktu_cetak' => $waktu_cetak,
'orders' => $order,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.selesai.pdf', $data);
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
public function countKonfirmasiPesanan(){
$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 countVerifikasiPesanan(){
$count = OrderDetail::where('status_order', 'Pending')->with('order')->whereHas('order', function($q){
$q->where('status_order', 'Lunas');
})->count();
return response()->json([
'status' => true,
'count' => $count,
]);
}
public function laporanPesanan(){
$data = [
'title' => 'Laporan Pesanan'
];
return view('dashboard.pesanan.laporan.pesanan.index', $data);
}
public function getLaporanPesanan(){
$tanggal = request('tanggal');
if(!empty($tanggal)){
$tanggalFormatted = collect($tanggal)->map(function ($tgl){
return Carbon::parse($tgl)->toDateString();
})->toArray();
}else{
$tanggalFormatted = [Carbon::now()->toDateString()];
}
$orders = self::helperLaporanPesanan($tanggalFormatted);
$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,
'entry_at' => $first->entry_at,
'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,
'cara_pembayaran' => $first->cara_pembayaran,
'medical_record' => $first->medical_record,
'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 helperLaporanPesanan($tanggalFormatted){
$data = DB::connection('dbOrderGizi')->table('public.order as o')
->leftJoin('public.order_detail as od', 'od.order_id', '=', 'o.order_id')
->where(['o.statusenabled' => true, 'o.status_order' => 'Lunas'])
->whereRaw(
"DATE(o.entry_at) IN (" . implode(',', array_fill(0, count($tanggalFormatted), '?')) . ")",
$tanggalFormatted
)
->select(
'o.order_id',
'o.entry_at',
'o.no_order',
'o.nama_pemesan',
'o.jenis_customer',
'o.total_harga',
'o.cara_pembayaran',
'o.status_order',
'o.bukti_pembayaran',
'o.note_dibatalkan',
'o.medical_record',
'od.status_order as detail_status_order'
)->get()->groupBy('order_id');
return $data;
}
public function exportLaporanPesanan(){
$startDate = Carbon::parse(request('start_date'))->startOfDay();
$endDate = Carbon::parse(request('end_date'))->endOfDay();
$type = request('type');
$type_customer = request('type_customer');
$query = Order::where('statusenabled', true)->where('status_order', 'Lunas');
if($type_customer !== 'all'){
$query->where('jenis_customer', $type_customer);
}
$order = $query->whereBetween('entry_at', [$startDate, $endDate])->with('orderDetail')->get();
if($type === 'pdf'){
return $this->pdfPesanan($startDate, $endDate, $order);
}else{
return $this->excelPesanan($startDate, $endDate, $order);
}
}
public function pdfPesanan($startDate, $endDate, $order){
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$data = [
'laporan' => 'Laporan Pesanan',
'waktu_cetak' => $waktu_cetak,
'orders' => $order,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted
];
$pdf = Pdf::loadView('dashboard.pesanan.pending.pdf', $data);
return $pdf->stream('laporan-pesanan-' . now()->format('Ymd-His') . '.pdf');
}
public function excelPesanan($startDate, $endDate, $order){
$startDateFormatted = Carbon::parse($startDate)->locale('id')->translatedFormat('d F Y');
$endDateFormatted = Carbon::parse($endDate)->locale('id')->translatedFormat('d F Y');
$waktu_cetak = Carbon::now()->locale('id')->translatedFormat('d F Y');
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', "Laporan Pesanan dari {$startDateFormatted} sampai {$endDateFormatted}");
$sheet->mergeCells('A1:G1');
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
$sheet->getStyle('A1')->getAlignment()->setHorizontal('center');
$sheet->setCellValue('A2', "Waktu Cetak: {$waktu_cetak}");
$sheet->mergeCells('A2:G2');
$sheet->getStyle('A2')->getAlignment()->setHorizontal('center');
// Header tabel
$headers = ["No", "Nomor Order", "Nama Customer", "Jenis Customer", "Tanggal Pesanan", "Total", "Detail Pesanan"];
$sheet->fromArray($headers, null, 'A4');
$sheet->getStyle('A4:G4')->getFont()->setBold(true);
$sheet->getStyle('A4:G4')->getAlignment()->setHorizontal('center');
$sheet->getStyle('A4:G4')->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
// Isi data
$row = 5;
foreach ($order as $index => $item) {
$sheet->setCellValue("A{$row}", $index + 1);
$sheet->setCellValue("B{$row}", $item->no_order);
$sheet->setCellValue("C{$row}", $item->nama_pemesan);
$sheet->setCellValue("D{$row}", $item->jenis_customer);
$sheet->setCellValue("E{$row}", Carbon::parse($item->entry_at)->translatedFormat('d F Y H:i'));
$sheet->setCellValue("F{$row}", $item->total_harga);
$sheet->setCellValue("G{$row}", $item->orderDetail->map(function ($detail) {
return $detail->nama_menu . ' x' . $detail->jumlah;
})->implode(', '));
// Border tiap baris
$sheet->getStyle("A{$row}:G{$row}")->getBorders()->getAllBorders()
->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
$row++;
}
// Auto size kolom
foreach(range('A', 'G') as $col){
$sheet->getColumnDimension($col)->setAutoSize(true);
}
$lastRow = $row - 1;
$sheet->setAutoFilter("A4:P{$lastRow}");
// Download file
$fileName = 'laporan-pesanan-' . now()->format('Ymd-His') . '.xlsx';
$writer = new Xlsx($spreadsheet);
// Output ke browser
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment; filename=\"{$fileName}\"");
header('Cache-Control: max-age=0');
$writer->save('php://output');
exit;
}
public function indexSemua(){
$payload = [
'title' => 'Semua Pesanan',
];
return view('dashboard.pesanan.semua.index', $payload);
}
public function getSemuaPekerjaan(){
$tanggal = request('tanggal');
if(!empty($tanggal)){
$tanggalFormatted = collect($tanggal)->map(function ($tgl){
return Carbon::parse($tgl)->toDateString();
})->toArray();
}else{
$tanggalFormatted = [Carbon::now()->toDateString()];
}
$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])
->whereRaw(
"DATE(o.entry_at) IN (" . implode(',', array_fill(0, count($tanggalFormatted), '?')) . ")",
$tanggalFormatted
)
->select(
'o.order_id',
'o.entry_at',
'o.no_order',
'o.nama_pemesan',
'o.jenis_customer',
'o.total_harga',
'o.cara_pembayaran',
'o.status_order',
'o.bukti_pembayaran',
'o.note_dibatalkan',
'o.medical_record',
'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,
'entry_at' => $first->entry_at,
'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,
'cara_pembayaran' => $first->cara_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()
]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}