get(); $markList = MarkList::where('status', 'active')->get(); return view('admin.dashboard', compact('orders', 'markList')); } // ------------------------------------------------------------------------- // STEP 1 : ADD TEMPORARY ITEM // ------------------------------------------------------------------------- public function addTempItem(Request $request) { // Validate item fields $item = $request->validate([ 'mark_no' => 'required', 'origin' => 'required', 'destination' => 'required', 'description' => 'required|string', 'ctn' => 'nullable|numeric', 'qty' => 'nullable|numeric', 'ttl_qty' => 'nullable|numeric', 'unit' => 'nullable|string', 'price' => 'nullable|numeric', 'ttl_amount' => 'nullable|numeric', 'cbm' => 'nullable|numeric', 'ttl_cbm' => 'nullable|numeric', 'kg' => 'nullable|numeric', 'ttl_kg' => 'nullable|numeric', 'shop_no' => 'nullable|string', ]); // ❌ Prevent changing mark_no once first item added if (session()->has('mark_no') && session('mark_no') != $request->mark_no) { return redirect()->to(route('admin.orders.index') . '#createOrderForm') ->with('error', 'You must finish or clear the current order before changing Mark No.'); } // Save mark, origin, destination ONLY ONCE if (!session()->has('mark_no')) { session([ 'mark_no' => $request->mark_no, 'origin' => $request->origin, 'destination' => $request->destination ]); } // ❌ DO NOT overwrite these values again // session(['mark_no' => $request->mark_no]); // session(['origin' => $request->origin]); // session(['destination' => $request->destination]); // Add new sub-item into session session()->push('temp_order_items', $item); return redirect()->to(route('admin.orders.index') . '#createOrderForm') ->with('success', 'Item added.'); } // ------------------------------------------------------------------------- // STEP 2 : DELETE TEMPORARY ITEM // ------------------------------------------------------------------------- public function deleteTempItem(Request $request) { $index = $request->index; $items = session('temp_order_items', []); if (isset($items[$index])) { unset($items[$index]); session(['temp_order_items' => array_values($items)]); } // If no items left → reset mark_no lock if (empty($items)) { session()->forget(['mark_no', 'origin', 'destination']); } return redirect()->to(route('admin.orders.index') . '#createOrderForm') ->with('success', 'Item removed successfully.'); } // ------------------------------------------------------------------------- // STEP 3 : FINISH ORDER // ------------------------------------------------------------------------- public function finishOrder(Request $request) { $request->validate([ 'mark_no' => 'required', 'origin' => 'required', 'destination' => 'required', ]); $items = session('temp_order_items', []); if (empty($items)) { return redirect()->to(route('admin.orders.index') . '#createOrderForm') ->with('error', 'Add at least one item before finishing.'); } // ======================= // GENERATE ORDER ID // ======================= $year = date('y'); $prefix = "KNT-$year-"; $lastOrder = Order::latest('id')->first(); $nextNumber = $lastOrder ? intval(substr($lastOrder->order_id, -8)) + 1 : 1; $orderId = $prefix . str_pad($nextNumber, 8, '0', STR_PAD_LEFT); // ======================= // TOTAL SUMS // ======================= $total_ctn = array_sum(array_column($items, 'ctn')); $total_qty = array_sum(array_column($items, 'qty')); $total_ttl_qty = array_sum(array_column($items, 'ttl_qty')); $total_amount = array_sum(array_column($items, 'ttl_amount')); $total_cbm = array_sum(array_column($items, 'cbm')); $total_ttl_cbm = array_sum(array_column($items, 'ttl_cbm')); $total_kg = array_sum(array_column($items, 'kg')); $total_ttl_kg = array_sum(array_column($items, 'ttl_kg')); // ======================= // CREATE ORDER // ======================= $order = Order::create([ 'order_id' => $orderId, 'mark_no' => $request->mark_no, 'origin' => $request->origin, 'destination' => $request->destination, 'ctn' => $total_ctn, 'qty' => $total_qty, 'ttl_qty' => $total_ttl_qty, 'ttl_amount' => $total_amount, 'cbm' => $total_cbm, 'ttl_cbm' => $total_ttl_cbm, 'kg' => $total_kg, 'ttl_kg' => $total_ttl_kg, 'status' => 'pending', ]); // SAVE ORDER ITEMS foreach ($items as $item) { OrderItem::create([ 'order_id' => $order->id, 'description' => $item['description'], 'ctn' => $item['ctn'], 'qty' => $item['qty'], 'ttl_qty' => $item['ttl_qty'], 'unit' => $item['unit'], 'price' => $item['price'], 'ttl_amount' => $item['ttl_amount'], 'cbm' => $item['cbm'], 'ttl_cbm' => $item['ttl_cbm'], 'kg' => $item['kg'], 'ttl_kg' => $item['ttl_kg'], 'shop_no' => $item['shop_no'], ]); } // ======================= // INVOICE CREATION START // ======================= // 1. Auto-generate invoice number $lastInvoice = \App\Models\Invoice::latest()->first(); $nextInvoice = $lastInvoice ? $lastInvoice->id + 1 : 1; $invoiceNumber = 'INV-' . date('Y') . '-' . str_pad($nextInvoice, 6, '0', STR_PAD_LEFT); // 2. Fetch customer (using mark list → customer_id) $markList = MarkList::where('mark_no', $order->mark_no)->first(); $customer = null; if ($markList && $markList->customer_id) { $customer = \App\Models\User::where('customer_id', $markList->customer_id)->first(); } // 3. Create Invoice Record $invoice = \App\Models\Invoice::create([ 'order_id' => $order->id, 'customer_id' => $customer->id ?? null, 'mark_no' => $order->mark_no, 'invoice_number' => $invoiceNumber, 'invoice_date' => now(), 'due_date' => now()->addDays(10), 'payment_method' => null, 'reference_no' => null, 'status' => 'pending', 'final_amount' => $total_amount, 'gst_percent' => 0, 'gst_amount' => 0, 'final_amount_with_gst' => $total_amount, // snapshot customer fields 'customer_name' => $customer->customer_name ?? null, 'company_name' => $customer->company_name ?? null, 'customer_email' => $customer->email ?? null, 'customer_mobile' => $customer->mobile_no ?? null, 'customer_address' => $customer->address ?? null, 'pincode' => $customer->pincode ?? null, 'notes' => null, ]); // 4. Clone order items into invoice_items foreach ($order->items as $item) { \App\Models\InvoiceItem::create([ 'invoice_id' => $invoice->id, 'description' => $item->description, 'ctn' => $item->ctn, 'qty' => $item->qty, 'ttl_qty' => $item->ttl_qty, 'unit' => $item->unit, 'price' => $item->price, 'ttl_amount' => $item->ttl_amount, 'cbm' => $item->cbm, 'ttl_cbm' => $item->ttl_cbm, 'kg' => $item->kg, 'ttl_kg' => $item->ttl_kg, 'shop_no' => $item->shop_no, ]); } // 5. TODO: PDF generation (I will add this later) $invoice->pdf_path = null; // placeholder for now $invoice->save(); // ======================= // END INVOICE CREATION // ======================= // CLEAR TEMP DATA session()->forget(['temp_order_items', 'mark_no', 'origin', 'destination']); return redirect()->route('admin.orders.index') ->with('success', 'Order + Invoice created successfully.'); } // ------------------------------------------------------------------------- // ORDER SHOW PAGE // ------------------------------------------------------------------------- public function show($id) { $order = Order::with('items', 'markList')->findOrFail($id); $user = null; if ($order->markList && $order->markList->customer_id) { $user = \App\Models\User::where('customer_id', $order->markList->customer_id)->first(); } return view('admin.orders_show', compact('order', 'user')); } public function popup($id) { // Load order with items + markList $order = Order::with(['items', 'markList'])->findOrFail($id); // Fetch user based on markList customer_id (same as show method) $user = null; if ($order->markList && $order->markList->customer_id) { $user = \App\Models\User::where('customer_id', $order->markList->customer_id)->first(); } return view('admin.popup', compact('order', 'user')); } public function resetTemp() { session()->forget(['temp_order_items', 'mark_no', 'origin', 'destination']); return redirect()->to(route('admin.orders.index') . '#createOrderForm') ->with('success', 'Order reset successfully.'); } public function orderShow() { $orders = Order::with([ 'markList', // company, customer, origin, destination, date 'shipments', // shipment_id, shipment_date, status 'invoice' // invoice number, dates, amounts, status ]) ->latest('id') // show latest orders first ->get(); return view('admin.orders', compact('orders')); } }