304 lines
11 KiB
PHP
304 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\File;
|
|
use App\Models\Layanan;
|
|
use App\Models\Pelanggan;
|
|
use App\Models\Reservasi;
|
|
use App\Models\SettingSistem;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class ApiReservasiController extends Controller
|
|
{
|
|
public function getAvailableSlots(Request $request)
|
|
{
|
|
// Jam buka dan tutup toko
|
|
$setting = SettingSistem::first();
|
|
$jamBuka = Carbon::createFromFormat('H:i:s', $setting->jam_operasional_buka);
|
|
|
|
if (Carbon::today()->toDateString() === $request->tanggal_pemesanan && Carbon::now()->greaterThan($jamBuka)) {
|
|
$tokoBuka = Carbon::now();
|
|
$tokoBuka->minute = ceil($tokoBuka->minute / 30) * 30;
|
|
if ($tokoBuka->minute === 60) {
|
|
$tokoBuka->addHour()->minute = 0;
|
|
}
|
|
$tokoBuka->second = 0;
|
|
} else {
|
|
$tokoBuka = $jamBuka;
|
|
}
|
|
$tokoTutup = Carbon::createFromFormat('H:i:s', $setting->jam_operasional_tutup);
|
|
|
|
// Data reservasi (contoh)
|
|
$reservations = Reservasi::where('tanggal_pemesanan', $request->tanggal_pemesanan)
|
|
->where('id_karyawan', $request->id_karyawan)
|
|
->whereIn('status', ['upcoming', 'processing'])
|
|
->get(['jam_awal', 'jam_berakhir'])
|
|
->map(function ($item) {
|
|
return [
|
|
'jam_awal' => $item->jam_awal, // Kolom dari database sudah dalam format string
|
|
'jam_berakhir' => $item->jam_berakhir,
|
|
];
|
|
})->toArray();
|
|
|
|
// Durasi layanan yang dipilih (dalam menit)
|
|
$layanan = Layanan::select('durasi')->find($request->id_layanan);
|
|
$serviceDuration = Carbon::parse($layanan->durasi)->hour * 60 + Carbon::parse($layanan->durasi)->minute;
|
|
|
|
// Konversi reservasi ke waktu
|
|
$reservations = collect($reservations)->map(function ($reservation) {
|
|
return [
|
|
'jam_awal' => Carbon::createFromFormat('H:i:s', $reservation['jam_awal']),
|
|
'jam_berakhir' => Carbon::createFromFormat('H:i:s', $reservation['jam_berakhir']),
|
|
];
|
|
});
|
|
|
|
// Cari slot kosong
|
|
$availableSlots = $this->findAvailableSlots($tokoBuka, $tokoTutup, $reservations, $serviceDuration);
|
|
|
|
return response()->json($availableSlots);
|
|
}
|
|
|
|
private function findAvailableSlots($tokoBuka, $tokoTutup, $reservations, $serviceDuration)
|
|
{
|
|
$availableSlots = [];
|
|
$startTime = $tokoBuka;
|
|
|
|
// Tambahkan dummy akhir untuk mempermudah perhitungan slot terakhir
|
|
$reservations = $reservations->sortBy('jam_awal');
|
|
$reservations->push(['jam_awal' => $tokoTutup, 'jam_berakhir' => $tokoTutup]);
|
|
|
|
foreach ($reservations as $reservation) {
|
|
$reservedStart = $reservation['jam_awal'];
|
|
$reservedEnd = $reservation['jam_berakhir'];
|
|
|
|
// Periksa apakah ada ruang antara waktu saat ini dan awal reservasi
|
|
while ($startTime->addMinutes($serviceDuration)->lte($reservedStart)) {
|
|
$availableSlots[] = [
|
|
'jam_awal' => $startTime->copy()->subMinutes($serviceDuration)->format('H:i:s'),
|
|
'jam_berakhir' => $startTime->format('H:i:s'),
|
|
];
|
|
}
|
|
|
|
// Set waktu mulai ke waktu selesai reservasi jika berada dalam slot
|
|
$startTime = max($startTime, $reservedEnd);
|
|
}
|
|
|
|
return $availableSlots;
|
|
}
|
|
|
|
public function getData($user_id)
|
|
{
|
|
$reservasi = Reservasi::with([
|
|
'layanans' => function ($query) {
|
|
$query->withTrashed();
|
|
},
|
|
'karyawans' => function ($query) {
|
|
$query->withTrashed();
|
|
}
|
|
])->where('id_user', $user_id)->whereIn('status', ['verification', 'upcoming', 'processing'])->whereRaw("STR_TO_DATE(CONCAT(tanggal_pemesanan, ' ', jam_berakhir), '%Y-%m-%d %H:%i:%s') >= ?", [now()])->orderByRaw("status = 'processing' DESC, created_at DESC")->get();
|
|
|
|
$data = [];
|
|
foreach ($reservasi as $r) {
|
|
$data[] = [
|
|
'id' => $r->id,
|
|
'tanggal_pemesanan' => $r->tanggal_pemesanan,
|
|
'jam_awal' => $r->jam_awal,
|
|
'karyawan' => $r->karyawans->nama,
|
|
'layanan' => $r->layanans->nama,
|
|
'status' => $r->status,
|
|
];
|
|
}
|
|
|
|
return response()->json($data);
|
|
}
|
|
|
|
public function getDataId($id)
|
|
{
|
|
$reservasi = Reservasi::with([
|
|
'layanans' => function ($query) {
|
|
$query->withTrashed();
|
|
},
|
|
'karyawans' => function ($query) {
|
|
$query->withTrashed();
|
|
}
|
|
])->findOrFail($id);
|
|
$data = [
|
|
'id' => $id,
|
|
'nama' => $reservasi->nama,
|
|
'tanggal_pemesanan' => $reservasi->tanggal_pemesanan,
|
|
'jam_awal' => $reservasi->jam_awal,
|
|
'jam_berakhir' => $reservasi->jam_berakhir,
|
|
'poin_digunakan' => $reservasi->poin_digunakan,
|
|
'biaya' => $reservasi->biaya,
|
|
'karyawan' => $reservasi->karyawans->nama,
|
|
'layanan' => $reservasi->layanans->nama,
|
|
'status' => $reservasi->status,
|
|
];
|
|
return response()->json($data);
|
|
}
|
|
|
|
public function getDataHistory($user_id)
|
|
{
|
|
$reservasi = Reservasi::with([
|
|
'layanans' => function ($query) {
|
|
$query->withTrashed();
|
|
},
|
|
'karyawans' => function ($query) {
|
|
$query->withTrashed();
|
|
}
|
|
])->where('id_user', $user_id)->orderBy('created_at', 'desc')->get();
|
|
|
|
$data = [];
|
|
foreach ($reservasi as $r) {
|
|
$data[] = [
|
|
'id' => $r->id,
|
|
'tanggal_pemesanan' => $r->tanggal_pemesanan,
|
|
'jam_awal' => $r->jam_awal,
|
|
'karyawan' => $r->karyawans->nama,
|
|
'layanan' => $r->layanans->nama,
|
|
'status' => $r->status,
|
|
];
|
|
}
|
|
|
|
return response()->json($data);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$layanan = Layanan::find($request->id_layanan);
|
|
|
|
// Konversi durasi layanan dari format H:i:s ke total menit
|
|
$durasiArray = explode(':', $layanan->durasi);
|
|
$durasiMenit = ($durasiArray[0] * 60) + $durasiArray[1];
|
|
|
|
// Hitung jam berakhir dengan menambahkan durasi dalam menit
|
|
$jam_berakhir = date("H:i:s", strtotime("+$durasiMenit minutes", strtotime($request->jam_awal)));
|
|
|
|
$conflict = Reservasi::where('tanggal_pemesanan', $request->tanggal_pemesanan)
|
|
->where('id_karyawan', $request->id_karyawan)
|
|
->whereIn('status', ['upcoming', 'processing'])
|
|
->where(function ($query) use ($request, $jam_berakhir) {
|
|
$query->where(function ($q) use ($request, $jam_berakhir) {
|
|
// Memastikan tidak ada tumpang tindih waktu
|
|
// Jika jam_awal baru berada di antara jam_awal lama dan jam_berakhir lama
|
|
$q->where('jam_awal', '<', $jam_berakhir)
|
|
->where('jam_berakhir', '>', $request->jam_awal);
|
|
})
|
|
->orWhere(function ($q) use ($request, $jam_berakhir) {
|
|
// Jika jam_berakhir baru berada di antara jam_awal lama dan jam_berakhir lama
|
|
$q->where('jam_awal', '<', $request->jam_awal)
|
|
->where('jam_berakhir', '>', $jam_berakhir);
|
|
});
|
|
})
|
|
->exists();
|
|
|
|
if ($conflict) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Waktu yang dipilih bertabrakan dengan reservasi lain.',
|
|
], 400);
|
|
}
|
|
|
|
// Simpan reservasi baru
|
|
$reservasi = Reservasi::create([
|
|
'nama' => $request->nama,
|
|
'tanggal_pemesanan' => $request->tanggal_pemesanan,
|
|
'jam_awal' => $request->jam_awal,
|
|
'jam_berakhir' => $jam_berakhir,
|
|
'poin_didapatkan' => $request->poin_didapatkan,
|
|
'poin_digunakan' => $request->poin_digunakan,
|
|
'biaya' => $request->biaya,
|
|
'id_layanan' => $request->id_layanan,
|
|
'id_user' => $request->id_user,
|
|
'id_karyawan' => $request->id_karyawan,
|
|
'status' => 'verification',
|
|
]);
|
|
|
|
$pelanggan = Pelanggan::where('id_user', $request->id_user)->first();
|
|
|
|
if ($pelanggan) {
|
|
$pelanggan->poin = $request->poin_total;
|
|
$pelanggan->save();
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'reservationId' => $reservasi->id
|
|
], 201);
|
|
}
|
|
|
|
public function getDataVerification($id){
|
|
$reservasi = Reservasi::with([
|
|
'layanans' => function ($query) {
|
|
$query->withTrashed();
|
|
},
|
|
'karyawans' => function ($query) {
|
|
$query->withTrashed();
|
|
}
|
|
])->findOrFail($id);
|
|
|
|
$data = [
|
|
'id' => $id,
|
|
'foto_payment' => $reservasi->foto_payment,
|
|
'created_at' => $reservasi->created_at,
|
|
];
|
|
return response()->json($data);
|
|
}
|
|
|
|
public function storeVerification(Request $request, $id)
|
|
{
|
|
$request->validate([
|
|
'imagePayment' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
|
|
]);
|
|
|
|
if ($request->hasFile('imagePayment')) {
|
|
try {
|
|
|
|
$file = $request->file('imagePayment');
|
|
$tujuan_upload = 'img/DataPayment';
|
|
$filegambar = time() . "_" . $file->getClientOriginalName();
|
|
$file->move($tujuan_upload, $filegambar);
|
|
|
|
$reservasi = Reservasi::with([
|
|
'layanans' => function ($query) {
|
|
$query->withTrashed();
|
|
},
|
|
'karyawans' => function ($query) {
|
|
$query->withTrashed();
|
|
}
|
|
])->findOrFail($id);
|
|
|
|
$last_upload = 'img/DataPayment/' . $reservasi->foto_payment;
|
|
if (File::exists($last_upload)) {
|
|
File::delete($last_upload);
|
|
}
|
|
|
|
$reservasi->foto_payment = $filegambar;
|
|
$reservasi->save();
|
|
|
|
return response()->json([
|
|
'message' => 'Image uploaded successfully'
|
|
], 200);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['message' => 'Failed to upload image'], 500);
|
|
}
|
|
}
|
|
|
|
return response()->json(['message' => 'No image found'], 400);
|
|
}
|
|
|
|
public function cancel($id)
|
|
{
|
|
$reservasi = Reservasi::find($id);
|
|
$currentTime = Carbon::now();
|
|
$reservasi->status = 'canceled';
|
|
$reservasi->cancelled_at = $currentTime;
|
|
$reservasi->save();
|
|
|
|
return response()->json(['message' => 'Pesanan berhasil dibatalkan.']);
|
|
}
|
|
}
|