Merge branch 'dev' of http://103.248.30.24:3000/kent-logistics/Kent-logistics-Laravel into dev
This commit is contained in:
@@ -91,8 +91,8 @@ class AdminOrderController extends Controller
|
||||
'status' => 'pending',
|
||||
]);
|
||||
|
||||
// If you want to auto-create an invoice at order creation, uncomment:
|
||||
// $this->createInvoice($order);
|
||||
//If you want to auto-create an invoice at order creation, uncomment:
|
||||
$this->createInvoice($order);
|
||||
|
||||
return redirect()->route('admin.orders.show', $order->id)
|
||||
->with('success', 'Order created successfully.');
|
||||
@@ -500,84 +500,193 @@ public function addTempItem(Request $request)
|
||||
session()->push('temp_order_items', $item);
|
||||
|
||||
return redirect()->to(route('admin.orders.index') . '#createOrderForm')
|
||||
->with('success', 'Item added.');
|
||||
|
||||
->with('success', 'Item added.');
|
||||
}
|
||||
|
||||
public function finishOrder(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'mark_no' => 'required',
|
||||
'origin' => 'required',
|
||||
'destination' => 'required',
|
||||
]);
|
||||
// -------------------------------------------------------------------------
|
||||
// STEP 3 : FINISH ORDER
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
$items = session('temp_order_items', []);
|
||||
public function finishOrder(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'mark_no' => 'required',
|
||||
'origin' => 'required',
|
||||
'destination' => 'required',
|
||||
]);
|
||||
|
||||
if (empty($items)) {
|
||||
return redirect()->to(route('admin.orders.index') . '#createOrderForm')
|
||||
->with('error', 'Add at least one item before finishing.');
|
||||
}
|
||||
$items = session('temp_order_items', []);
|
||||
|
||||
// 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 ALL SUB-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'],
|
||||
]);
|
||||
}
|
||||
|
||||
// CLEAR TEMP DATA
|
||||
session()->forget(['temp_order_items', 'mark_no', 'origin', 'destination']);
|
||||
|
||||
return redirect()->route('admin.orders.index')
|
||||
->with('success', 'Order saved successfully.');
|
||||
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 CRUD: update / destroy
|
||||
// ---------------------------
|
||||
public function updateItem(Request $request, $id)
|
||||
{
|
||||
$item = OrderItem::findOrFail($id);
|
||||
|
||||
$item->update([
|
||||
'description' => $request->description,
|
||||
'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,
|
||||
]);
|
||||
|
||||
return back()->with('success', 'Item updated successfully!');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Shipment;
|
||||
@@ -106,6 +107,9 @@ class ShipmentController extends Controller
|
||||
'order_qty' => $order->qty,
|
||||
'order_ttl_qty' => $order->ttl_qty,
|
||||
'order_ttl_amount' => $order->ttl_amount,
|
||||
'order_cbm' => $order->cbm,
|
||||
'order_ttl_cbm' => $order->ttl_cbm,
|
||||
'order_kg' => $order->kg,
|
||||
'order_ttl_kg' => $order->ttl_kg,
|
||||
]);
|
||||
}
|
||||
@@ -113,24 +117,112 @@ class ShipmentController extends Controller
|
||||
return redirect()->back()->with('success', "Shipment $newShipmentId created successfully!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Show shipment details (for modal popup)
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$shipment = Shipment::with('orders')->findOrFail($id);
|
||||
|
||||
return view('admin.shipments.show', [
|
||||
'shipment' => $shipment,
|
||||
'orders' => $shipment->orders,
|
||||
'isViewMode' => false // This is the edit mode
|
||||
]);
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$shipment = Shipment::findOrFail($id);
|
||||
$mode = request()->get('mode', 'view');
|
||||
|
||||
// Load full order data from orders table
|
||||
$orders = Order::whereIn('id',
|
||||
ShipmentItem::where('shipment_id', $id)->pluck('order_id')
|
||||
)->get();
|
||||
$shipment = Shipment::with(['items.order'])->findOrFail($id);
|
||||
|
||||
return response()->json([
|
||||
// Get orders from shipment items
|
||||
$orders = collect();
|
||||
foreach ($shipment->items as $item) {
|
||||
if ($item->order) {
|
||||
$orders->push($item->order);
|
||||
}
|
||||
}
|
||||
|
||||
// Get orders not assigned to any shipment (available orders)
|
||||
$usedOrderIds = ShipmentItem::pluck('order_id')->toArray();
|
||||
$availableOrders = Order::whereNotIn('id', $usedOrderIds)->get();
|
||||
|
||||
return view('admin.view-shipment', [
|
||||
'shipment' => $shipment,
|
||||
'orders' => $orders
|
||||
'orders' => $orders,
|
||||
'mode' => $mode,
|
||||
'availableOrders' => $availableOrders
|
||||
]);
|
||||
}
|
||||
|
||||
public function addOrders(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
'order_ids' => 'required|array|min:1'
|
||||
]);
|
||||
|
||||
$shipment = Shipment::findOrFail($id);
|
||||
$orderIds = $request->order_ids;
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
$orders = Order::whereIn('id', $orderIds)->get();
|
||||
$addedOrders = [];
|
||||
|
||||
foreach ($orders as $order) {
|
||||
// Prevent duplicates
|
||||
if (ShipmentItem::where('shipment_id', $shipment->id)->where('order_id', $order->id)->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ShipmentItem::create([
|
||||
'shipment_id' => $shipment->id,
|
||||
'order_id' => $order->id,
|
||||
'order_ctn' => $order->ctn,
|
||||
'order_qty' => $order->qty,
|
||||
'order_ttl_qty' => $order->ttl_qty,
|
||||
'order_ttl_amount' => $order->ttl_amount,
|
||||
'order_cbm' => $order->cbm,
|
||||
'order_ttl_cbm' => $order->ttl_cbm,
|
||||
'order_kg' => $order->kg,
|
||||
'order_ttl_kg' => $order->ttl_kg,
|
||||
]);
|
||||
|
||||
$addedOrders[] = $order;
|
||||
}
|
||||
|
||||
// Recalculate totals
|
||||
$this->recalculateShipmentTotals($shipment->id);
|
||||
|
||||
DB::commit();
|
||||
|
||||
$shipment->refresh();
|
||||
$shipment->load('items.order');
|
||||
|
||||
// Get updated orders list
|
||||
$updatedOrders = collect();
|
||||
foreach ($shipment->items as $item) {
|
||||
if ($item->order) {
|
||||
$updatedOrders->push($item->order);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Orders added to shipment successfully.',
|
||||
'shipment' => $shipment,
|
||||
'orders' => $addedOrders
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Failed to add orders: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Shipment status from action button
|
||||
*/
|
||||
@@ -209,4 +301,77 @@ class ShipmentController extends Controller
|
||||
return redirect()->route('admin.shipments')
|
||||
->with('success', 'Shipment deleted successfully.');
|
||||
}
|
||||
|
||||
public function removeOrder(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'shipment_id' => 'required|exists:shipments,id',
|
||||
'order_id' => 'required|exists:orders,id'
|
||||
]);
|
||||
|
||||
$shipmentId = $request->shipment_id;
|
||||
$orderId = $request->order_id;
|
||||
|
||||
// Get order data before deletion
|
||||
$order = Order::findOrFail($orderId);
|
||||
|
||||
// Delete pivot entry
|
||||
ShipmentItem::where('shipment_id', $shipmentId)
|
||||
->where('order_id', $orderId)
|
||||
->delete();
|
||||
|
||||
// Recalculate totals
|
||||
$shipment = $this->recalculateShipmentTotals($shipmentId);
|
||||
|
||||
if ($request->ajax() || $request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Order removed successfully.',
|
||||
'order' => $order,
|
||||
'shipment' => $shipment
|
||||
]);
|
||||
}
|
||||
|
||||
return back()->with('success', 'Order removed successfully.');
|
||||
}
|
||||
|
||||
private function recalculateShipmentTotals($shipmentId)
|
||||
{
|
||||
$shipment = Shipment::with('items')->findOrFail($shipmentId);
|
||||
|
||||
// Use the shipment items to calculate totals
|
||||
$shipment->total_ctn = $shipment->items->sum('order_ctn');
|
||||
$shipment->total_qty = $shipment->items->sum('order_qty');
|
||||
$shipment->total_ttl_qty = $shipment->items->sum('order_ttl_qty');
|
||||
$shipment->total_amount = $shipment->items->sum('order_ttl_amount');
|
||||
$shipment->total_cbm = $shipment->items->sum('order_cbm');
|
||||
$shipment->total_ttl_cbm = $shipment->items->sum('order_ttl_cbm');
|
||||
$shipment->total_kg = $shipment->items->sum('order_kg');
|
||||
$shipment->total_ttl_kg = $shipment->items->sum('order_ttl_kg');
|
||||
|
||||
$shipment->save();
|
||||
$shipment->refresh(); // Refresh to get updated data
|
||||
|
||||
return $shipment;
|
||||
}
|
||||
|
||||
// Helper method to get available orders for a shipment
|
||||
public function getAvailableOrders($shipmentId)
|
||||
{
|
||||
$shipment = Shipment::findOrFail($shipmentId);
|
||||
|
||||
// Get all used order IDs
|
||||
$usedOrderIds = ShipmentItem::pluck('order_id')->toArray();
|
||||
|
||||
// Remove orders that are already in this shipment
|
||||
$shipmentOrderIds = $shipment->items->pluck('order_id')->toArray();
|
||||
$availableOrderIds = array_diff($usedOrderIds, $shipmentOrderIds);
|
||||
|
||||
$availableOrders = Order::whereNotIn('id', $availableOrderIds)->get();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'availableOrders' => $availableOrders
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -84,11 +84,25 @@ class UserProfileController extends Controller
|
||||
$user->profile_image = $folder . $filename;
|
||||
$user->save();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Profile image updated successfully',
|
||||
'profile_image' => url($user->profile_image),
|
||||
]);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Profile image updated successfully',
|
||||
'data' => [
|
||||
'customer_id' => $user->customer_id,
|
||||
'customer_name' => $user->customer_name,
|
||||
'company_name' => $user->company_name,
|
||||
'designation' => $user->designation,
|
||||
'email' => $user->email,
|
||||
'mobile' => $user->mobile_no,
|
||||
'address' => $user->address,
|
||||
'pincode' => $user->pincode,
|
||||
'status' => $user->status,
|
||||
'customer_type' => $user->customer_type,
|
||||
'profile_image' => url($user->profile_image),
|
||||
'date' => $user->date,
|
||||
]
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user