2025-11-12 11:56:43 +05:30
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
|
|
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use App\Models\Order;
|
2025-11-13 13:05:17 +05:30
|
|
|
use App\Models\OrderItem;
|
|
|
|
|
use App\Models\MarkList;
|
2025-12-01 10:38:52 +05:30
|
|
|
use App\Models\Invoice;
|
|
|
|
|
use App\Models\InvoiceItem;
|
|
|
|
|
use App\Models\User;
|
2025-12-22 22:38:35 +05:30
|
|
|
use PDF;
|
2025-12-03 10:35:20 +05:30
|
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
|
|
use App\Exports\OrdersExport;
|
2025-12-23 12:22:35 +05:30
|
|
|
use App\Imports\OrderItemsPreviewImport;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
|
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-11-12 11:56:43 +05:30
|
|
|
class AdminOrderController extends Controller
|
|
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* LIST / DASHBOARD
|
|
|
|
|
* ---------------------------*/
|
2025-11-12 11:56:43 +05:30
|
|
|
public function index()
|
|
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
$orders = Order::latest()->get();
|
2025-11-13 13:05:17 +05:30
|
|
|
$markList = MarkList::where('status', 'active')->get();
|
2025-11-12 11:56:43 +05:30
|
|
|
|
|
|
|
|
return view('admin.dashboard', compact('orders', 'markList'));
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* CREATE NEW ORDER (simple page)
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
public function create()
|
2025-11-13 13:05:17 +05:30
|
|
|
{
|
2025-12-01 10:38:52 +05:30
|
|
|
$markList = MarkList::where('status', 'active')->get();
|
|
|
|
|
return view('admin.orders_create', compact('markList'));
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* SHOW / POPUP
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
public function show($id)
|
|
|
|
|
{
|
|
|
|
|
$order = Order::with('items', 'markList')->findOrFail($id);
|
2025-12-22 22:38:35 +05:30
|
|
|
$user = $this->getCustomerFromOrder($order);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return view('admin.orders_show', compact('order', 'user'));
|
2025-11-13 13:05:17 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
public function popup($id)
|
|
|
|
|
{
|
|
|
|
|
$order = Order::with(['items', 'markList'])->findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$user = null;
|
|
|
|
|
if ($order->markList && $order->markList->customer_id) {
|
|
|
|
|
$user = User::where('customer_id', $order->markList->customer_id)->first();
|
|
|
|
|
}
|
2025-12-01 10:38:52 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
return view('admin.popup', compact('order', 'user'));
|
|
|
|
|
}
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* ORDER ITEM MANAGEMENT (existing orders)
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
public function addItem(Request $request, $orderId)
|
2025-11-13 13:05:17 +05:30
|
|
|
{
|
2025-12-01 10:38:52 +05:30
|
|
|
$order = Order::findOrFail($orderId);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$data = $request->validate([
|
|
|
|
|
'description' => 'required|string',
|
2025-12-22 22:38:35 +05:30
|
|
|
'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',
|
2025-12-01 10:38:52 +05:30
|
|
|
]);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$data['order_id'] = $order->id;
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
OrderItem::create($data);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$this->recalcTotals($order);
|
2025-12-22 22:38:35 +05:30
|
|
|
$this->updateInvoiceFromOrder($order);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return redirect()->back()->with('success', 'Item added and totals updated.');
|
|
|
|
|
}
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
public function deleteItem($id)
|
|
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
$item = OrderItem::findOrFail($id);
|
2025-12-01 10:38:52 +05:30
|
|
|
$order = $item->order;
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
$item->delete();
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$this->recalcTotals($order);
|
2025-12-05 17:16:02 +05:30
|
|
|
$this->updateInvoiceFromOrder($order);
|
|
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return redirect()->back()->with('success', 'Item deleted and totals updated.');
|
2025-11-17 10:33:11 +05:30
|
|
|
}
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
public function restoreItem($id)
|
|
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
$item = OrderItem::withTrashed()->findOrFail($id);
|
2025-12-01 10:38:52 +05:30
|
|
|
$order = Order::findOrFail($item->order_id);
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$item->restore();
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$this->recalcTotals($order);
|
2025-12-05 17:16:02 +05:30
|
|
|
$this->updateInvoiceFromOrder($order);
|
|
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return redirect()->back()->with('success', 'Item restored and totals updated.');
|
2025-11-17 10:33:11 +05:30
|
|
|
}
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* ORDER CRUD: update / destroy
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
public function update(Request $request, $id)
|
|
|
|
|
{
|
|
|
|
|
$order = Order::findOrFail($id);
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$data = $request->validate([
|
2025-12-22 22:38:35 +05:30
|
|
|
'mark_no' => 'required|string',
|
|
|
|
|
'origin' => 'nullable|string',
|
2025-12-01 10:38:52 +05:30
|
|
|
'destination' => 'nullable|string',
|
|
|
|
|
]);
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$order->update([
|
2025-12-22 22:38:35 +05:30
|
|
|
'mark_no' => $data['mark_no'],
|
|
|
|
|
'origin' => $data['origin'] ?? null,
|
2025-12-01 10:38:52 +05:30
|
|
|
'destination' => $data['destination'] ?? null,
|
|
|
|
|
]);
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$this->recalcTotals($order);
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return redirect()->route('admin.orders.show', $order->id)
|
2025-12-22 22:38:35 +05:30
|
|
|
->with('success', 'Order updated successfully.');
|
2025-12-01 10:38:52 +05:30
|
|
|
}
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
public function destroy($id)
|
|
|
|
|
{
|
|
|
|
|
$order = Order::findOrFail($id);
|
2025-11-17 10:33:11 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
OrderItem::where('order_id', $order->id)->delete();
|
|
|
|
|
$order->delete();
|
2025-11-12 19:44:04 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return redirect()->route('admin.orders.index')
|
2025-12-22 22:38:35 +05:30
|
|
|
->with('success', 'Order deleted successfully.');
|
2025-12-01 10:38:52 +05:30
|
|
|
}
|
2025-11-12 19:44:04 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* HELPERS
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
private function recalcTotals(Order $order)
|
|
|
|
|
{
|
|
|
|
|
$items = $order->items()->get();
|
|
|
|
|
|
|
|
|
|
$order->update([
|
2025-12-22 22:38:35 +05:30
|
|
|
'ctn' => (int) $items->sum(fn($i) => (int) ($i->ctn ?? 0)),
|
|
|
|
|
'qty' => (int) $items->sum(fn($i) => (int) ($i->qty ?? 0)),
|
|
|
|
|
'ttl_qty' => (int) $items->sum(fn($i) => (int) ($i->ttl_qty ?? 0)),
|
|
|
|
|
'ttl_amount' => (float) $items->sum(fn($i) => (float) ($i->ttl_amount ?? 0)),
|
|
|
|
|
'cbm' => (float) $items->sum(fn($i) => (float) ($i->cbm ?? 0)),
|
|
|
|
|
'ttl_cbm' => (float) $items->sum(fn($i) => (float) ($i->ttl_cbm ?? 0)),
|
|
|
|
|
'kg' => (float) $items->sum(fn($i) => (float) ($i->kg ?? 0)),
|
|
|
|
|
'ttl_kg' => (float) $items->sum(fn($i) => (float) ($i->ttl_kg ?? 0)),
|
2025-12-01 10:38:52 +05:30
|
|
|
]);
|
2025-11-13 13:05:17 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
private function generateOrderId()
|
2025-11-15 10:08:43 +05:30
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
$year = date('y');
|
2025-12-01 10:38:52 +05:30
|
|
|
$prefix = "KNT-$year-";
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
$lastOrder = Order::latest('id')->first();
|
2025-12-01 10:38:52 +05:30
|
|
|
$nextNumber = $lastOrder ? intval(substr($lastOrder->order_id, -8)) + 1 : 1;
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return $prefix . str_pad($nextNumber, 8, '0', STR_PAD_LEFT);
|
2025-11-15 10:08:43 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* INVOICE CREATION HELPERS
|
|
|
|
|
* ---------------------------*/
|
2025-12-01 10:38:52 +05:30
|
|
|
private function createInvoice(Order $order)
|
|
|
|
|
{
|
|
|
|
|
$invoiceNumber = $this->generateInvoiceNumber();
|
2025-12-22 22:38:35 +05:30
|
|
|
$customer = $this->getCustomerFromMarkList($order->mark_no);
|
|
|
|
|
$totalAmount = $order->ttl_amount;
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
$invoice = Invoice::create([
|
2025-12-22 22:38:35 +05:30
|
|
|
'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' => $totalAmount,
|
|
|
|
|
'gst_percent' => 0,
|
|
|
|
|
'gst_amount' => 0,
|
2025-12-01 10:38:52 +05:30
|
|
|
'final_amount_with_gst' => $totalAmount,
|
2025-12-22 22:38:35 +05:30
|
|
|
'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,
|
|
|
|
|
'pdf_path' => null,
|
2025-12-01 10:38:52 +05:30
|
|
|
]);
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
foreach ($order->items as $item) {
|
|
|
|
|
InvoiceItem::create([
|
2025-12-22 22:38:35 +05:30
|
|
|
'invoice_id' => $invoice->id,
|
2025-12-01 10:38:52 +05:30
|
|
|
'description' => $item->description,
|
2025-12-22 22:38:35 +05:30
|
|
|
'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,
|
2025-12-01 10:38:52 +05:30
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
private function generateInvoiceNumber()
|
2025-11-13 13:05:17 +05:30
|
|
|
{
|
2025-12-01 10:38:52 +05:30
|
|
|
$lastInvoice = Invoice::latest()->first();
|
|
|
|
|
$nextInvoice = $lastInvoice ? $lastInvoice->id + 1 : 1;
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
return 'INV-' . date('Y') . '-' . str_pad($nextInvoice, 6, '0', STR_PAD_LEFT);
|
2025-11-12 11:56:43 +05:30
|
|
|
}
|
2025-11-12 19:44:04 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
private function getCustomerFromMarkList($markNo)
|
2025-11-26 23:07:12 +05:30
|
|
|
{
|
2025-12-01 10:38:52 +05:30
|
|
|
$markList = MarkList::where('mark_no', $markNo)->first();
|
2025-11-26 23:07:12 +05:30
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
if ($markList && $markList->customer_id) {
|
|
|
|
|
return User::where('customer_id', $markList->customer_id)->first();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
2025-11-26 23:07:12 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-01 10:38:52 +05:30
|
|
|
private function getCustomerFromOrder($order)
|
|
|
|
|
{
|
|
|
|
|
if ($order->markList && $order->markList->customer_id) {
|
|
|
|
|
return User::where('customer_id', $order->markList->customer_id)->first();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-11-13 13:05:17 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* SEE (detailed)
|
|
|
|
|
* ---------------------------*/
|
2025-12-19 11:12:06 +05:30
|
|
|
public function see($id)
|
|
|
|
|
{
|
|
|
|
|
$order = Order::with([
|
|
|
|
|
'markList',
|
|
|
|
|
'items',
|
|
|
|
|
'invoice.items',
|
|
|
|
|
'shipments' => function ($q) use ($id) {
|
|
|
|
|
$q->whereHas('orders', function ($oq) use ($id) {
|
|
|
|
|
$oq->where('orders.id', $id)
|
2025-12-22 22:38:35 +05:30
|
|
|
->whereNull('orders.deleted_at');
|
2025-12-19 11:12:06 +05:30
|
|
|
})->with([
|
|
|
|
|
'orders' => function ($oq) use ($id) {
|
|
|
|
|
$oq->where('orders.id', $id)
|
2025-12-22 22:38:35 +05:30
|
|
|
->whereNull('orders.deleted_at')
|
|
|
|
|
->with('items');
|
2025-12-19 11:12:06 +05:30
|
|
|
}
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
])->findOrFail($id);
|
|
|
|
|
|
|
|
|
|
$orderData = [
|
|
|
|
|
'order_id' => $order->order_id,
|
|
|
|
|
'status' => $order->status,
|
|
|
|
|
'totals' => [
|
2025-12-22 22:38:35 +05:30
|
|
|
'ctn' => $order->ctn,
|
|
|
|
|
'qty' => $order->qty,
|
|
|
|
|
'ttl_qty' => $order->ttl_qty,
|
|
|
|
|
'cbm' => $order->cbm,
|
|
|
|
|
'ttl_cbm' => $order->ttl_cbm,
|
|
|
|
|
'kg' => $order->kg,
|
|
|
|
|
'ttl_kg' => $order->ttl_kg,
|
|
|
|
|
'amount' => $order->ttl_amount,
|
2025-12-19 11:12:06 +05:30
|
|
|
],
|
|
|
|
|
'items' => $order->items,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$shipmentsData = [];
|
|
|
|
|
foreach ($order->shipments as $shipment) {
|
|
|
|
|
$shipmentOrders = [];
|
|
|
|
|
$totals = [
|
|
|
|
|
'ctn' => 0, 'qty' => 0, 'ttl_qty' => 0,
|
|
|
|
|
'cbm' => 0, 'ttl_cbm' => 0,
|
2025-12-22 22:38:35 +05:30
|
|
|
'kg' => 0, 'ttl_kg' => 0,
|
2025-12-19 11:12:06 +05:30
|
|
|
'amount' => 0,
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
foreach ($shipment->orders as $shipOrder) {
|
|
|
|
|
foreach ($shipOrder->items as $item) {
|
|
|
|
|
$shipmentOrders[] = [
|
|
|
|
|
'order_id' => $shipOrder->order_id,
|
|
|
|
|
'origin' => $shipOrder->origin,
|
|
|
|
|
'destination' => $shipOrder->destination,
|
|
|
|
|
'description' => $item->description,
|
|
|
|
|
'ctn' => $item->ctn,
|
|
|
|
|
'qty' => $item->qty,
|
|
|
|
|
'ttl_qty' => $item->ttl_qty,
|
|
|
|
|
'amount' => $item->ttl_amount,
|
|
|
|
|
];
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
$totals['ctn'] += $item->ctn;
|
|
|
|
|
$totals['qty'] += $item->qty;
|
|
|
|
|
$totals['ttl_qty'] += $item->ttl_qty;
|
|
|
|
|
$totals['cbm'] += $item->cbm;
|
|
|
|
|
$totals['ttl_cbm'] += $item->ttl_cbm;
|
|
|
|
|
$totals['kg'] += $item->kg;
|
|
|
|
|
$totals['ttl_kg'] += $item->ttl_kg;
|
|
|
|
|
$totals['amount'] += $item->ttl_amount;
|
2025-12-19 11:12:06 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (empty($shipmentOrders)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$shipmentsData[] = [
|
|
|
|
|
'shipment_id' => $shipment->shipment_id,
|
|
|
|
|
'status' => $shipment->status,
|
|
|
|
|
'date' => $shipment->shipment_date,
|
|
|
|
|
'total_orders' => 1,
|
|
|
|
|
'orders' => $shipmentOrders,
|
|
|
|
|
'totals' => $totals,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$invoiceData = null;
|
|
|
|
|
if ($order->invoice) {
|
|
|
|
|
$invoice = $order->invoice;
|
|
|
|
|
$invoiceData = [
|
2025-12-22 22:38:35 +05:30
|
|
|
'invoice_no' => $invoice->invoice_number,
|
|
|
|
|
'status' => $invoice->status,
|
2025-12-19 11:12:06 +05:30
|
|
|
'invoice_date' => $invoice->invoice_date,
|
|
|
|
|
'due_date' => $invoice->due_date,
|
2025-12-22 22:38:35 +05:30
|
|
|
'customer' => [
|
2025-12-19 11:12:06 +05:30
|
|
|
'name' => $invoice->customer_name,
|
|
|
|
|
'mobile' => $invoice->customer_mobile,
|
|
|
|
|
'email' => $invoice->customer_email,
|
|
|
|
|
'address' => $invoice->customer_address,
|
|
|
|
|
'pincode' => $invoice->pincode,
|
|
|
|
|
],
|
2025-12-22 22:38:35 +05:30
|
|
|
'items' => $invoice->items,
|
2025-12-19 11:12:06 +05:30
|
|
|
'summary' => [
|
|
|
|
|
'amount' => $invoice->final_amount,
|
|
|
|
|
'cgst' => 0,
|
|
|
|
|
'sgst' => 0,
|
|
|
|
|
'total' => $invoice->final_amount_with_gst,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('admin.see_order', compact(
|
|
|
|
|
'order',
|
|
|
|
|
'orderData',
|
|
|
|
|
'shipmentsData',
|
|
|
|
|
'invoiceData'
|
|
|
|
|
));
|
|
|
|
|
}
|
2025-11-15 10:08:43 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* FILTERED LIST + EXPORTS
|
|
|
|
|
* ---------------------------*/
|
2025-12-19 16:15:18 +05:30
|
|
|
public function orderShow()
|
|
|
|
|
{
|
|
|
|
|
$orders = Order::with([
|
2025-12-22 22:38:35 +05:30
|
|
|
'markList',
|
|
|
|
|
'shipments',
|
|
|
|
|
'invoice'
|
|
|
|
|
])->latest('id')->get();
|
2025-12-19 11:12:06 +05:30
|
|
|
|
2025-12-19 16:15:18 +05:30
|
|
|
return view('admin.orders', compact('orders'));
|
|
|
|
|
}
|
2025-12-01 10:34:27 +05:30
|
|
|
|
2025-12-05 17:16:02 +05:30
|
|
|
private function buildOrdersQueryFromRequest(Request $request)
|
2025-12-22 22:38:35 +05:30
|
|
|
{
|
|
|
|
|
$query = Order::query()
|
|
|
|
|
->with(['markList', 'invoice', 'shipments']);
|
2025-12-19 11:12:06 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
if ($request->filled('search')) {
|
|
|
|
|
$search = trim($request->search);
|
2025-12-19 11:12:06 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
$query->where(function ($q) use ($search) {
|
|
|
|
|
$q->where('orders.order_id', 'like', "%{$search}%")
|
2025-12-19 11:12:06 +05:30
|
|
|
->orWhereHas('markList', function ($q2) use ($search) {
|
|
|
|
|
$q2->where('company_name', 'like', "%{$search}%")
|
|
|
|
|
->orWhere('customer_id', 'like', "%{$search}%")
|
|
|
|
|
->orWhere('origin', 'like', "%{$search}%")
|
|
|
|
|
->orWhere('destination', 'like', "%{$search}%");
|
|
|
|
|
})
|
|
|
|
|
->orWhereHas('invoice', function ($q3) use ($search) {
|
|
|
|
|
$q3->where('invoice_number', 'like', "%{$search}%");
|
|
|
|
|
})
|
|
|
|
|
->orWhereHas('shipments', function ($q4) use ($search) {
|
|
|
|
|
$q4->where('shipments.shipment_id', 'like', "%{$search}%");
|
|
|
|
|
});
|
2025-12-22 22:38:35 +05:30
|
|
|
});
|
2025-12-05 17:16:02 +05:30
|
|
|
}
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
if ($request->filled('status')) {
|
|
|
|
|
$query->where(function ($q) use ($request) {
|
|
|
|
|
$q->whereHas('invoice', function ($q2) use ($request) {
|
|
|
|
|
$q2->where('status', $request->status);
|
|
|
|
|
})->orWhereDoesntHave('invoice');
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-12-03 15:36:04 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
if ($request->filled('shipment')) {
|
|
|
|
|
$query->where(function ($q) use ($request) {
|
|
|
|
|
$q->whereHas('shipments', function ($q2) use ($request) {
|
|
|
|
|
$q2->where('status', $request->shipment);
|
|
|
|
|
})->orWhereDoesntHave('shipments');
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
if ($request->filled('from_date')) {
|
|
|
|
|
$query->whereDate('orders.created_at', '>=', $request->from_date);
|
|
|
|
|
}
|
2025-11-26 23:07:12 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
if ($request->filled('to_date')) {
|
|
|
|
|
$query->whereDate('orders.created_at', '<=', $request->to_date);
|
|
|
|
|
}
|
2025-12-19 11:12:06 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
return $query->latest('orders.id');
|
|
|
|
|
}
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
public function downloadPdf(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$orders = $this->buildOrdersQueryFromRequest($request)->get();
|
2025-12-05 17:16:02 +05:30
|
|
|
$filters = [
|
2025-12-19 11:12:06 +05:30
|
|
|
'search' => $request->search,
|
|
|
|
|
'status' => $request->status,
|
|
|
|
|
'shipment' => $request->shipment,
|
|
|
|
|
'from' => $request->from_date,
|
|
|
|
|
'to' => $request->to_date,
|
2025-12-05 17:16:02 +05:30
|
|
|
];
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-12-05 17:16:02 +05:30
|
|
|
$pdf = PDF::loadView('admin.orders.pdf', compact('orders', 'filters'))
|
2025-12-22 22:38:35 +05:30
|
|
|
->setPaper('a4', 'landscape');
|
2025-12-03 10:35:20 +05:30
|
|
|
|
2025-12-19 11:12:06 +05:30
|
|
|
return $pdf->download(
|
|
|
|
|
'orders-report-' . now()->format('Y-m-d') . '.pdf'
|
|
|
|
|
);
|
2025-12-22 22:38:35 +05:30
|
|
|
}
|
2025-12-01 10:34:27 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
public function downloadExcel(Request $request)
|
|
|
|
|
{
|
|
|
|
|
return Excel::download(
|
2025-12-19 11:12:06 +05:30
|
|
|
new OrdersExport($request),
|
|
|
|
|
'orders-report-' . now()->format('Y-m-d') . '.xlsx'
|
|
|
|
|
);
|
2025-12-01 12:45:25 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* --------------------------------------------------
|
|
|
|
|
* NEW: Create Order + Invoice directly from popup
|
|
|
|
|
* route: admin.orders.temp.add (Create New Order form)
|
|
|
|
|
* --------------------------------------------------*/
|
|
|
|
|
public function addTempItem(Request $request)
|
2025-12-05 17:16:02 +05:30
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
// 1) order-level fields
|
2025-12-05 17:16:02 +05:30
|
|
|
$request->validate([
|
2025-12-22 22:38:35 +05:30
|
|
|
'mark_no' => 'required',
|
|
|
|
|
'origin' => 'required',
|
2025-12-05 17:16:02 +05:30
|
|
|
'destination' => 'required',
|
|
|
|
|
]);
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 2) multi-row items
|
|
|
|
|
$items = $request->validate([
|
|
|
|
|
'items' => 'required|array',
|
|
|
|
|
'items.*.description' => 'required|string',
|
|
|
|
|
'items.*.ctn' => 'nullable|numeric',
|
|
|
|
|
'items.*.qty' => 'nullable|numeric',
|
|
|
|
|
'items.*.ttl_qty' => 'nullable|numeric',
|
|
|
|
|
'items.*.unit' => 'nullable|string',
|
|
|
|
|
'items.*.price' => 'nullable|numeric',
|
|
|
|
|
'items.*.ttl_amount' => 'nullable|numeric',
|
|
|
|
|
'items.*.cbm' => 'nullable|numeric',
|
|
|
|
|
'items.*.ttl_cbm' => 'nullable|numeric',
|
|
|
|
|
'items.*.kg' => 'nullable|numeric',
|
|
|
|
|
'items.*.ttl_kg' => 'nullable|numeric',
|
|
|
|
|
'items.*.shop_no' => 'nullable|string',
|
|
|
|
|
])['items'];
|
|
|
|
|
|
|
|
|
|
// रिकामे rows काढा
|
|
|
|
|
$items = array_filter($items, function ($row) {
|
|
|
|
|
return trim($row['description'] ?? '') !== '';
|
|
|
|
|
});
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-05 17:16:02 +05:30
|
|
|
if (empty($items)) {
|
2025-12-22 22:38:35 +05:30
|
|
|
return back()->with('error', 'Add at least one item.');
|
2025-12-05 17:16:02 +05:30
|
|
|
}
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 3) totals
|
|
|
|
|
$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'));
|
2025-12-05 17:16:02 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 4) order id generate
|
|
|
|
|
$orderId = $this->generateOrderId();
|
2025-12-05 17:16:02 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 5) order create
|
2025-12-05 17:16:02 +05:30
|
|
|
$order = Order::create([
|
2025-12-22 22:38:35 +05:30
|
|
|
'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,
|
2025-12-05 17:16:02 +05:30
|
|
|
'ttl_amount' => $total_amount,
|
2025-12-22 22:38:35 +05:30
|
|
|
'cbm' => $total_cbm,
|
|
|
|
|
'ttl_cbm' => $total_ttl_cbm,
|
|
|
|
|
'kg' => $total_kg,
|
|
|
|
|
'ttl_kg' => $total_ttl_kg,
|
2025-12-23 00:36:15 +05:30
|
|
|
'status' => 'order_placed',
|
2025-12-03 15:36:04 +05:30
|
|
|
]);
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 6) order items
|
2025-12-05 17:16:02 +05:30
|
|
|
foreach ($items as $item) {
|
|
|
|
|
OrderItem::create([
|
2025-12-22 22:38:35 +05:30
|
|
|
'order_id' => $order->id,
|
|
|
|
|
'description'=> $item['description'],
|
|
|
|
|
'ctn' => $item['ctn'],
|
|
|
|
|
'qty' => $item['qty'],
|
|
|
|
|
'ttl_qty' => $item['ttl_qty'],
|
|
|
|
|
'unit' => $item['unit'],
|
|
|
|
|
'price' => $item['price'],
|
2025-12-05 17:16:02 +05:30
|
|
|
'ttl_amount' => $item['ttl_amount'],
|
2025-12-22 22:38:35 +05:30
|
|
|
'cbm' => $item['cbm'],
|
|
|
|
|
'ttl_cbm' => $item['ttl_cbm'],
|
|
|
|
|
'kg' => $item['kg'],
|
|
|
|
|
'ttl_kg' => $item['ttl_kg'],
|
|
|
|
|
'shop_no' => $item['shop_no'],
|
2025-12-05 17:16:02 +05:30
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 7) invoice number
|
|
|
|
|
$invoiceNumber = $this->generateInvoiceNumber();
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 8) customer fetch
|
2025-12-05 17:16:02 +05:30
|
|
|
$markList = MarkList::where('mark_no', $order->mark_no)->first();
|
|
|
|
|
$customer = null;
|
|
|
|
|
if ($markList && $markList->customer_id) {
|
2025-12-22 22:38:35 +05:30
|
|
|
$customer = User::where('customer_id', $markList->customer_id)->first();
|
2025-12-05 17:16:02 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 9) invoice create
|
|
|
|
|
$invoice = 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,
|
2025-12-05 17:16:02 +05:30
|
|
|
'final_amount_with_gst' => $total_amount,
|
2025-12-22 22:38:35 +05:30
|
|
|
'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,
|
|
|
|
|
'pdf_path' => null,
|
2025-12-01 12:45:25 +05:30
|
|
|
]);
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
// 10) invoice items
|
2025-12-05 17:16:02 +05:30
|
|
|
foreach ($order->items as $item) {
|
2025-12-22 22:38:35 +05:30
|
|
|
InvoiceItem::create([
|
|
|
|
|
'invoice_id' => $invoice->id,
|
2025-12-05 17:16:02 +05:30
|
|
|
'description' => $item->description,
|
2025-12-22 22:38:35 +05:30
|
|
|
'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,
|
2025-12-05 17:16:02 +05:30
|
|
|
]);
|
|
|
|
|
}
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-05 17:16:02 +05:30
|
|
|
return redirect()->route('admin.orders.index')
|
2025-12-22 22:38:35 +05:30
|
|
|
->with('success', 'Order + Invoice created successfully.');
|
2025-12-05 17:16:02 +05:30
|
|
|
}
|
2025-12-03 15:36:04 +05:30
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
/* ---------------------------
|
|
|
|
|
* UPDATE ORDER ITEM (existing orders)
|
|
|
|
|
* ---------------------------*/
|
2025-12-05 17:16:02 +05:30
|
|
|
public function updateItem(Request $request, $id)
|
2025-12-03 16:13:37 +05:30
|
|
|
{
|
2025-12-22 22:38:35 +05:30
|
|
|
$item = OrderItem::findOrFail($id);
|
2025-12-05 17:16:02 +05:30
|
|
|
$order = $item->order;
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-03 16:13:37 +05:30
|
|
|
$item->update([
|
|
|
|
|
'description' => $request->description,
|
2025-12-05 17:16:02 +05:30
|
|
|
'ctn' => $request->ctn,
|
|
|
|
|
'qty' => $request->qty,
|
|
|
|
|
'ttl_qty' => $request->ttl_qty,
|
|
|
|
|
'unit' => $request->unit,
|
|
|
|
|
'price' => $request->price,
|
|
|
|
|
'ttl_amount' => $request->ttl_amount,
|
|
|
|
|
'cbm' => $request->cbm,
|
|
|
|
|
'ttl_cbm' => $request->ttl_cbm,
|
|
|
|
|
'kg' => $request->kg,
|
|
|
|
|
'ttl_kg' => $request->ttl_kg,
|
|
|
|
|
'shop_no' => $request->shop_no,
|
2025-12-03 16:13:37 +05:30
|
|
|
]);
|
2025-12-01 12:45:25 +05:30
|
|
|
|
2025-12-05 17:16:02 +05:30
|
|
|
$this->recalcTotals($order);
|
2025-12-22 22:38:35 +05:30
|
|
|
$this->updateInvoiceFromOrder($order);
|
2025-12-05 17:16:02 +05:30
|
|
|
|
|
|
|
|
return back()->with('success', 'Item updated successfully');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function updateInvoiceFromOrder(Order $order)
|
|
|
|
|
{
|
|
|
|
|
$invoice = Invoice::where('order_id', $order->id)->first();
|
|
|
|
|
|
|
|
|
|
if (!$invoice) {
|
2025-12-22 22:38:35 +05:30
|
|
|
return;
|
2025-12-05 17:16:02 +05:30
|
|
|
}
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
$invoice->final_amount = $order->ttl_amount;
|
|
|
|
|
$invoice->gst_percent = 0;
|
|
|
|
|
$invoice->gst_amount = 0;
|
2025-12-05 17:16:02 +05:30
|
|
|
$invoice->final_amount_with_gst = $order->ttl_amount;
|
|
|
|
|
$invoice->save();
|
|
|
|
|
|
|
|
|
|
InvoiceItem::where('invoice_id', $invoice->id)->delete();
|
|
|
|
|
|
|
|
|
|
foreach ($order->items as $item) {
|
|
|
|
|
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,
|
|
|
|
|
]);
|
|
|
|
|
}
|
2025-12-03 16:13:37 +05:30
|
|
|
}
|
2025-12-23 12:22:35 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function uploadExcelPreview(Request $request)
|
|
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$request->validate([
|
|
|
|
|
'excel' => 'required|file|mimes:xlsx,xls'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$import = new OrderItemsPreviewImport();
|
|
|
|
|
Excel::import($import, $request->file('excel'));
|
|
|
|
|
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => true,
|
|
|
|
|
'items' => $import->rows
|
|
|
|
|
]);
|
|
|
|
|
} catch (ValidationException $e) {
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Invalid Excel file format'
|
|
|
|
|
], 422);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
\Log::error($e);
|
|
|
|
|
return response()->json([
|
|
|
|
|
'success' => false,
|
|
|
|
|
'message' => 'Server error'
|
|
|
|
|
], 500);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-12-22 22:38:35 +05:30
|
|
|
}
|