148 lines
5.9 KiB
PHP
Executable File
148 lines
5.9 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Controllers\User;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\{Additional, BookingFoto, DetailAdditional, PaketFoto, Pelanggan};
|
|
use App\Http\Requests\User\BookingFotoRequest;
|
|
use App\Services\WhatsAppService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use Carbon\Carbon;
|
|
|
|
|
|
class BookingFotoController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$foto = PaketFoto::latest()->get();
|
|
|
|
return view('user/booking-foto', compact('foto'));
|
|
}
|
|
public function detail($id)
|
|
{
|
|
$foto = PaketFoto::findOrFail($id);
|
|
\Carbon\Carbon::setLocale('id');
|
|
$additionals = Additional::all();
|
|
$start = \Carbon\Carbon::now();
|
|
$end = \Carbon\Carbon::now()->addMonth();
|
|
$prevMonth = $start->copy()->subMonth();
|
|
$nextMonth = $start->copy()->addMonth();
|
|
$currentMonthLabel = $start->isoFormat('MMMM YYYY');
|
|
return view('user.detail-foto', compact('foto', 'additionals', 'start', 'end', 'currentMonthLabel', 'prevMonth', 'nextMonth'));
|
|
}
|
|
public function loadCalendar(Request $request)
|
|
{
|
|
\Carbon\Carbon::setLocale('id');
|
|
$month = $request->month ?? date('m');
|
|
$year = $request->year ?? date('Y');
|
|
$start = \Carbon\Carbon::createFromDate($year, $month, 1);
|
|
$prevMonth = $start->copy()->subMonth();
|
|
$nextMonth = $start->copy()->addMonth();
|
|
$currentMonthLabel = $start->isoFormat('MMMM YYYY');
|
|
$html = view('user.components.calendar-grid', compact(
|
|
'start',
|
|
'prevMonth',
|
|
'nextMonth',
|
|
'currentMonthLabel'
|
|
))->render();
|
|
|
|
return response()->json(['html' => $html]);
|
|
}
|
|
public function cekSlot(Request $request)
|
|
{
|
|
|
|
$booked = BookingFoto::where('tgl_booking', $request->tanggal)
|
|
->whereIn('status_booking', ['menunggu_verifikasi', 'diterima', 'selesai'])
|
|
->get(['jam_mulai']);
|
|
|
|
return response()->json($booked);
|
|
}
|
|
public function formulir(Request $request)
|
|
{
|
|
$details = $this->calculateDetails($request);
|
|
if (!session()->has('payment_deadline')) {
|
|
session()->put('payment_deadline', now()->addHours(2));
|
|
}
|
|
$sisaWaktu = now()->diffInSeconds(session('payment_deadline'), false);
|
|
if ($sisaWaktu <= 0) {
|
|
session()->forget(['payment_deadline', 'addons']);
|
|
return redirect()->route('booking.foto')->with('error', 'Waktu pembayaran telah habis.');
|
|
}
|
|
return view('user.pembayaran-foto', array_merge($details, [
|
|
'sisaWaktu' => $sisaWaktu,
|
|
'request' => $request
|
|
]));
|
|
}
|
|
public function cancelBooking()
|
|
{
|
|
session()->forget(['payment_deadline', 'addons']);
|
|
return redirect()->route('booking.foto');
|
|
}
|
|
public function store(BookingFotoRequest $request)
|
|
{
|
|
$details = $this->calculateDetails($request);
|
|
return DB::transaction(function () use ($request, $details) {
|
|
if (BookingFoto::where(['tgl_booking' => $request->tgl_booking, 'jam_mulai' => $request->jam_mulai])
|
|
->whereIn('status_booking', ['menunggu_verifikasi', 'diterima'])->exists()
|
|
) {
|
|
return back()->with('error', 'Slot baru saja diambil orang lain.');
|
|
}
|
|
$pelanggan = Pelanggan::firstOrCreate(['no_wa' => $request->no_wa], ['nama' => $request->nama]);
|
|
$pathBukti = $request->hasFile('bukti_bayar')
|
|
? $request->file('bukti_bayar')->store('img/payment/foto', 'public')
|
|
: null;
|
|
$booking = BookingFoto::create([
|
|
'no_invoice' => 'INV-FOTO-' . strtoupper(Str::random(6)),
|
|
'id_pelanggan' => $pelanggan->id_pelanggan,
|
|
'id_paket' => $details['foto']->id_paket,
|
|
'tgl_booking' => $request->tgl_booking,
|
|
'jam_mulai' => $request->jam_mulai,
|
|
'jam_selesai' => $details['jamSelesaiBaru'],
|
|
'total_bayar' => $details['grandTotal'],
|
|
'bukti_bayar' => $pathBukti,
|
|
'status_booking' => 'menunggu_verifikasi'
|
|
]);
|
|
foreach ($details['addonsDetails'] as $item) {
|
|
DetailAdditional::create([
|
|
'id_booking' => $booking->id_booking,
|
|
'id_additional' => $item['id'],
|
|
'qty' => $item['qty'],
|
|
'subtotal' => $item['subtotal']
|
|
]);
|
|
}
|
|
$urlWA = WhatsAppService::getBookingFotoMessage($booking, $details['foto'], $details['addonsDetails'], $details['grandTotal'], $details['jamSelesaiBaru']);
|
|
session()->forget('payment_deadline');
|
|
|
|
return redirect()->route('booking.foto')->with(['success' => 'Pesanan Berhasil!', 'waUrl' => $urlWA]);
|
|
});
|
|
}
|
|
private function calculateDetails($request)
|
|
{
|
|
$foto = PaketFoto::findOrFail($request->id_paket);
|
|
$totalAddon = 0;
|
|
$tambahanMenit = 0;
|
|
$addonsDetails = [];
|
|
|
|
if ($request->has('addons')) {
|
|
foreach ($request->addons as $id => $qty) {
|
|
if ($qty > 0 && $add = Additional::find($id)) {
|
|
$subtotal = $add->harga * $qty;
|
|
$totalAddon += $subtotal;
|
|
if ($id == 4) $tambahanMenit += (5 * $qty);
|
|
if ($id == 6) $tambahanMenit += (10 * $qty);
|
|
$addonsDetails[] = ['nama' => $add->nama, 'qty' => $qty, 'subtotal' => $subtotal, 'id' => $id];
|
|
}
|
|
}
|
|
}
|
|
return [
|
|
'foto' => $foto,
|
|
'addonsDetails' => $addonsDetails,
|
|
'grandTotal' => $foto->harga + $totalAddon,
|
|
'jamSelesaiBaru' => Carbon::createFromFormat('H:i', $request->jam_mulai)
|
|
->addMinutes($foto->durasi + $tambahanMenit)->format('H:i')
|
|
];
|
|
}
|
|
}
|