merge resolve conflict
This commit is contained in:
@@ -11,6 +11,71 @@ use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AdminAccountController extends Controller
|
||||
{
|
||||
public function updateEntry(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->validate([
|
||||
'entry_no' => 'required|exists:entries,entry_no',
|
||||
'description' => 'required|string|max:255',
|
||||
'order_quantity' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$entry = Entry::where('entry_no', $data['entry_no'])->first();
|
||||
|
||||
if (!$entry) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Entry not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$entry->description = $data['description'];
|
||||
$entry->order_quantity = $data['order_quantity'];
|
||||
$entry->save();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Entry updated successfully.',
|
||||
'entry' => $entry,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Server error: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteEntry(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->validate([
|
||||
'entry_no' => 'required|exists:entries,entry_no',
|
||||
]);
|
||||
|
||||
$entry = Entry::where('entry_no', $data['entry_no'])->first();
|
||||
|
||||
if (!$entry) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Entry not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$entry->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Entry deleted successfully.',
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Server error: '.$e->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 🚀 1. Get dashboard entries
|
||||
*/
|
||||
@@ -245,4 +310,82 @@ class AdminAccountController extends Controller
|
||||
'pending' => $entry->pending_amount,
|
||||
]);
|
||||
}
|
||||
|
||||
//--------------------------
|
||||
//add order Entry
|
||||
//--------------------------
|
||||
public function addOrdersToEntry(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'entry_no' => 'required|exists:entries,entry_no',
|
||||
'order_ids' => 'required|array',
|
||||
'order_ids.*' => 'integer|exists:orders,id',
|
||||
]);
|
||||
|
||||
return DB::transaction(function () use ($data) {
|
||||
$entry = Entry::where('entry_no', $data['entry_no'])->firstOrFail();
|
||||
|
||||
// आधीचे orders काढू नका, फक्त नवीन add करा
|
||||
$entry->orders()->syncWithoutDetaching($data['order_ids']);
|
||||
|
||||
// इथे quantity auto update
|
||||
$entry->order_quantity = $entry->orders()->count();
|
||||
$entry->save();
|
||||
|
||||
$entry->load('orders');
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Orders added successfully.',
|
||||
'entry' => $entry,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getEntryOrders($entry_no)
|
||||
{
|
||||
$entry = Entry::where('entry_no', $entry_no)
|
||||
->with('orders')
|
||||
->first();
|
||||
|
||||
if (!$entry) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Entry not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'orders' => $entry->orders,
|
||||
]);
|
||||
}
|
||||
|
||||
public function removeOrderFromEntry(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'entry_no' => 'required|exists:entries,entry_no',
|
||||
'order_id' => 'required|integer|exists:orders,id',
|
||||
]);
|
||||
|
||||
return DB::transaction(function () use ($data) {
|
||||
$entry = Entry::where('entry_no', $data['entry_no'])->firstOrFail();
|
||||
|
||||
// order detach करा
|
||||
$entry->orders()->detach($data['order_id']);
|
||||
|
||||
// इथे quantity auto update
|
||||
$entry->order_quantity = $entry->orders()->count();
|
||||
$entry->save();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Order removed successfully.',
|
||||
'entry' => $entry,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,14 +28,14 @@ class AdminOrderController extends Controller
|
||||
/**
|
||||
* Orders list (detailed)
|
||||
*/
|
||||
public function orderShow()
|
||||
{
|
||||
$orders = Order::with(['markList', 'shipments', 'invoice'])
|
||||
->latest('id')
|
||||
->get();
|
||||
// public function orderShow()
|
||||
// {
|
||||
// $orders = Order::with(['markList', 'shipments', 'invoice'])
|
||||
// ->latest('id')
|
||||
// ->get();
|
||||
|
||||
return view('admin.orders', compact('orders'));
|
||||
}
|
||||
// return view('admin.orders', compact('orders'));
|
||||
// }
|
||||
|
||||
// ---------------------------
|
||||
// CREATE NEW ORDER (simple DB flow)
|
||||
@@ -105,13 +105,13 @@ class AdminOrderController extends Controller
|
||||
return view('admin.orders_show', compact('order', 'user'));
|
||||
}
|
||||
|
||||
public function popup($id)
|
||||
{
|
||||
$order = Order::with(['items', 'markList'])->findOrFail($id);
|
||||
$user = $this->getCustomerFromOrder($order);
|
||||
// public function popup($id)
|
||||
// {
|
||||
// $order = Order::with(['items', 'markList'])->findOrFail($id);
|
||||
// $user = $this->getCustomerFromOrder($order);
|
||||
|
||||
return view('admin.popup', compact('order', 'user'));
|
||||
}
|
||||
// return view('admin.popup', compact('order', 'user'));
|
||||
// }
|
||||
|
||||
// ---------------------------
|
||||
// ORDER ITEM MANAGEMENT (DB)
|
||||
@@ -340,4 +340,84 @@ class AdminOrderController extends Controller
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
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'));
|
||||
}
|
||||
|
||||
public function downloadPdf(Request $request)
|
||||
{
|
||||
$query = Order::with(['markList', 'invoice', 'shipments']);
|
||||
|
||||
// Apply filters
|
||||
if ($request->has('search') && $request->search) {
|
||||
$search = $request->search;
|
||||
$query->where(function($q) use ($search) {
|
||||
$q->where('order_id', 'like', "%{$search}%")
|
||||
->orWhereHas('markList', function($q) use ($search) {
|
||||
$q->where('company_name', 'like', "%{$search}%");
|
||||
})
|
||||
->orWhereHas('invoice', function($q) use ($search) {
|
||||
$q->where('invoice_number', 'like', "%{$search}%");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->has('status') && $request->status) {
|
||||
$query->whereHas('invoice', function($q) use ($request) {
|
||||
$q->where('status', $request->status);
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->has('shipment') && $request->shipment) {
|
||||
$query->whereHas('shipments', function($q) use ($request) {
|
||||
$q->where('status', $request->shipment);
|
||||
});
|
||||
}
|
||||
|
||||
$orders = $query->get();
|
||||
|
||||
$pdf = PDF::loadView('admin.orders.pdf', compact('orders'));
|
||||
return $pdf->download('orders-report-' . date('Y-m-d') . '.pdf');
|
||||
}
|
||||
|
||||
public function downloadExcel(Request $request)
|
||||
{
|
||||
return Excel::download(new OrdersExport($request), 'orders-report-' . date('Y-m-d') . '.xlsx');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
43
resources/views/admin/pdf/order_pdf.blade.php
Normal file
43
resources/views/admin/pdf/order_pdf.blade.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Orders Report</title>
|
||||
<style>
|
||||
body { font-family: DejaVu Sans, sans-serif; font-size: 12px; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
||||
th, td { border: 1px solid #ccc; padding: 6px 8px; text-align: left; }
|
||||
th { background: #f3f4f6; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Orders Report</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order ID</th>
|
||||
<th>Company</th>
|
||||
<th>Invoice No</th>
|
||||
<th>Invoice Status</th>
|
||||
<th>Shipment Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($orders as $order)
|
||||
@php
|
||||
$mark = $order->markList ?? null;
|
||||
$invoice = $order->invoice ?? null;
|
||||
$shipment = $order->shipments->first() ?? null;
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $order->order_id ?? '-' }}</td>
|
||||
<td>{{ $mark->company_name ?? '-' }}</td>
|
||||
<td>{{ $invoice->invoice_number ?? '-' }}</td>
|
||||
<td>{{ $invoice->status ?? '-' }}</td>
|
||||
<td>{{ $shipment->status ?? '-' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -189,7 +189,101 @@
|
||||
filter: brightness(0) saturate(100%) invert(84%) sepia(8%) saturate(165%) hue-rotate(179deg) brightness(89%) contrast(86%);
|
||||
}
|
||||
|
||||
/* Responsive pagination */
|
||||
/* ===== UPDATED SEARCH BAR STYLES ===== */
|
||||
.search-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
flex: 1;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.search-input-group {
|
||||
display: flex;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-right: none;
|
||||
padding: 10px 16px;
|
||||
font-size: 14px;
|
||||
background-color: #fff;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
outline: none;
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.search-button {
|
||||
background: #3b82f6;
|
||||
border: 1px solid #3b82f6;
|
||||
color: white;
|
||||
padding: 10px 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.search-button:hover {
|
||||
background: #2563eb;
|
||||
border-color: #2563eb;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.status-badges {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 6px 12px;
|
||||
border-radius: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.status-badge-pending {
|
||||
background: linear-gradient(135deg, #fef3c7, #fde68a);
|
||||
color: #d97706;
|
||||
border: 1px solid #f59e0b;
|
||||
}
|
||||
|
||||
.status-badge-approved {
|
||||
background: linear-gradient(135deg, #d1fae5, #a7f3d0);
|
||||
color: #065f46;
|
||||
border: 1px solid #10b981;
|
||||
}
|
||||
|
||||
.status-badge-rejected {
|
||||
background: linear-gradient(135deg, #fecaca, #fca5a5);
|
||||
color: #991b1b;
|
||||
border: 1px solid #ef4444;
|
||||
}
|
||||
|
||||
/* Responsive styles */
|
||||
@media (max-width: 768px) {
|
||||
.pagination-container {
|
||||
flex-direction: column;
|
||||
@@ -199,28 +293,50 @@
|
||||
.pagination-controls {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.status-badges {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Counts -->
|
||||
<div class="d-flex justify-content-between align-items-center mb-2 mt-3">
|
||||
<h4 class="fw-bold mb-0">User Requests (Total: {{ $total }})</h4>
|
||||
<div>
|
||||
<span class="count-badge badge rounded-pill bg-warning text-dark me-1">{{ $requests->where('status', 'pending')->count() }} Pending</span>
|
||||
<span class="count-badge badge rounded-pill bg-success me-1">{{ $requests->where('status', 'approved')->count() }} Approved</span>
|
||||
<span class="count-badge badge rounded-pill bg-danger">{{ $requests->where('status', 'rejected')->count() }} Rejected</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Search + Table -->
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-body pb-1">
|
||||
<form method="GET" action="">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="search" value="{{ request('search') }}" class="form-control" placeholder="🔍 Search by name, email, company...">
|
||||
<button class="btn btn-outline-primary" type="submit"><i class="bi bi-search"></i></button>
|
||||
<!-- Updated Search Bar with Status Badges in the same line -->
|
||||
<div class="search-container">
|
||||
<form method="GET" action="" class="search-form">
|
||||
<div class="search-input-group">
|
||||
<input type="text" name="search" value="{{ request('search') }}" class="search-input" placeholder="Search by name, email, company...">
|
||||
<button class="search-button" type="submit">
|
||||
<svg class="search-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 21L16.514 16.506L21 21ZM19 10.5C19 15.194 15.194 19 10.5 19C5.806 19 2 15.194 2 10.5C2 5.806 5.806 2 10.5 2C15.194 2 19 5.806 19 10.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="status-badges">
|
||||
<span class="status-badge status-badge-pending">{{ $requests->where('status', 'pending')->count() }} Pending</span>
|
||||
<span class="status-badge status-badge-approved">{{ $requests->where('status', 'approved')->count() }} Approved</span>
|
||||
<span class="status-badge status-badge-rejected">{{ $requests->where('status', 'rejected')->count() }} Rejected</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive custom-table-wrapper">
|
||||
<table class="table align-middle mb-0 custom-table">
|
||||
|
||||
@@ -218,33 +218,67 @@ Route::prefix('admin')
|
||||
->name('admin.customers.status');
|
||||
});
|
||||
|
||||
// ==========================================
|
||||
// ADMIN ACCOUNT (AJAX) ROUTES
|
||||
// ==========================================
|
||||
Route::prefix('admin/account')
|
||||
->middleware('auth:admin')
|
||||
->name('admin.account.')
|
||||
->group(function () {
|
||||
|
||||
Route::get('/dashboard', [AdminAccountController::class, 'getDashboardData'])
|
||||
->name('dashboard');
|
||||
|
||||
Route::get('/available-orders', [AdminAccountController::class, 'getAvailableOrders'])
|
||||
->name('orders.available');
|
||||
|
||||
Route::post('/create-order', [AdminAccountController::class, 'accountCreateOrder'])
|
||||
->name('create');
|
||||
|
||||
Route::post('/toggle-payment', [AdminAccountController::class, 'togglePayment'])
|
||||
->name('toggle');
|
||||
|
||||
Route::post('/installment/create', [AdminAccountController::class, 'addInstallment'])
|
||||
->name('installment.create');
|
||||
|
||||
Route::post('/installment/update-status', [AdminAccountController::class, 'updateInstallmentStatus'])
|
||||
->name('installment.update');
|
||||
|
||||
Route::get('/entry/{entry_no}', [AdminAccountController::class, 'getEntryDetails'])
|
||||
->name('entry.details');
|
||||
|
||||
// ⬇⬇ NEW ROUTES FOR EDIT + DELETE ⬇⬇
|
||||
Route::post('/update-entry', [AdminAccountController::class, 'updateEntry'])
|
||||
->name('update.entry');
|
||||
|
||||
Route::post('/delete-entry', [AdminAccountController::class, 'deleteEntry'])
|
||||
->name('delete.entry');
|
||||
|
||||
// ==========================================
|
||||
// ADMIN ACCOUNT (AJAX) ROUTES
|
||||
// ==========================================
|
||||
Route::prefix('admin/account')
|
||||
->middleware('auth:admin')
|
||||
->name('admin.account.')
|
||||
->group(function () {
|
||||
|
||||
Route::get('/dashboard', [AdminAccountController::class, 'getDashboardData'])
|
||||
->name('dashboard');
|
||||
// ===== Associated Orders Routes (EDIT MODAL साठी) =====
|
||||
Route::post('/add-orders-to-entry', [AdminAccountController::class, 'addOrdersToEntry'])
|
||||
->name('add.orders.to.entry');
|
||||
|
||||
Route::get('/entry-orders/{entry_no}', [AdminAccountController::class, 'getEntryOrders'])
|
||||
->name('entry.orders');
|
||||
|
||||
Route::post('/remove-order-from-entry', [AdminAccountController::class, 'removeOrderFromEntry'])
|
||||
->name('remove.order.from.entry');
|
||||
|
||||
Route::get('/available-orders', [AdminAccountController::class, 'getAvailableOrders'])
|
||||
->name('orders.available');
|
||||
|
||||
});
|
||||
|
||||
Route::post('/create-order', [AdminAccountController::class, 'accountCreateOrder'])
|
||||
->name('create');
|
||||
|
||||
|
||||
Route::post('/toggle-payment', [AdminAccountController::class, 'togglePayment'])
|
||||
->name('toggle');
|
||||
|
||||
Route::post('/installment/create', [AdminAccountController::class, 'addInstallment'])
|
||||
->name('installment.create');
|
||||
// ---------------------------
|
||||
// REPORTS DOWNLOAD ROUTES
|
||||
// ---------------------------
|
||||
Route::get('/admin/orders/download/pdf', [OrderController::class, 'downloadPdf'])->name('admin.orders.download.pdf');
|
||||
Route::get('/admin/orders/download/excel', [OrderController::class, 'downloadExcel'])->name('admin.orders.download.excel');
|
||||
|
||||
Route::post('/installment/update-status', [AdminAccountController::class, 'updateInstallmentStatus'])
|
||||
->name('installment.update');
|
||||
//---------------------------
|
||||
//Edit Button Route
|
||||
//---------------------------
|
||||
|
||||
|
||||
Route::get('/entry/{entry_no}', [AdminAccountController::class, 'getEntryDetails'])
|
||||
->name('entry.details');
|
||||
});
|
||||
Reference in New Issue
Block a user