Merge branch 'dev' of http://103.248.30.24:3000/kent-logistics/Kent-logistics-Laravel into dev
This commit is contained in:
@@ -19,9 +19,12 @@ class AdminCustomerController extends Controller
|
|||||||
$search = $request->search;
|
$search = $request->search;
|
||||||
$status = $request->status;
|
$status = $request->status;
|
||||||
|
|
||||||
$query = User::with(['marks', 'orders'])->orderBy('id', 'desc');
|
$query = User::with([
|
||||||
|
'marks',
|
||||||
|
'orders',
|
||||||
|
'invoices.installments' // 🔥 IMPORTANT
|
||||||
|
])->orderBy('id', 'desc');
|
||||||
|
|
||||||
// SEARCH FILTER
|
|
||||||
if (!empty($search)) {
|
if (!empty($search)) {
|
||||||
$query->where(function ($q) use ($search) {
|
$query->where(function ($q) use ($search) {
|
||||||
$q->where('customer_name', 'like', "%$search%")
|
$q->where('customer_name', 'like', "%$search%")
|
||||||
@@ -31,20 +34,22 @@ class AdminCustomerController extends Controller
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// STATUS FILTER
|
|
||||||
if (!empty($status) && in_array($status, ['active', 'inactive'])) {
|
if (!empty($status) && in_array($status, ['active', 'inactive'])) {
|
||||||
$query->where('status', $status);
|
$query->where('status', $status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all customers for statistics (without pagination)
|
|
||||||
$allCustomers = $query->get();
|
$allCustomers = $query->get();
|
||||||
|
|
||||||
// Get paginated customers for the table (10 per page)
|
|
||||||
$customers = $query->paginate(10);
|
$customers = $query->paginate(10);
|
||||||
|
|
||||||
return view('admin.customers', compact('customers', 'allCustomers', 'search', 'status'));
|
return view('admin.customers', compact(
|
||||||
|
'customers',
|
||||||
|
'allCustomers',
|
||||||
|
'search',
|
||||||
|
'status'
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// SHOW ADD CUSTOMER FORM
|
// SHOW ADD CUSTOMER FORM
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
@@ -106,20 +111,36 @@ class AdminCustomerController extends Controller
|
|||||||
// VIEW CUSTOMER FULL DETAILS
|
// VIEW CUSTOMER FULL DETAILS
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
public function view($id)
|
public function view($id)
|
||||||
{
|
{
|
||||||
$customer = User::with(['marks', 'orders'])->findOrFail($id);
|
$customer = User::with([
|
||||||
|
'marks',
|
||||||
|
'orders',
|
||||||
|
'invoices.installments'
|
||||||
|
])->findOrFail($id);
|
||||||
|
|
||||||
|
// Orders
|
||||||
$totalOrders = $customer->orders->count();
|
$totalOrders = $customer->orders->count();
|
||||||
$totalAmount = $customer->orders->sum('ttl_amount');
|
$totalOrderAmount = $customer->orders->sum('ttl_amount');
|
||||||
$recentOrders = $customer->orders()->latest()->take(5)->get();
|
|
||||||
|
// Invoices (PAYABLE)
|
||||||
|
$totalPayable = $customer->invoices->sum('final_amount_with_gst');
|
||||||
|
|
||||||
|
// Paid via installments
|
||||||
|
$totalPaid = $customer->invoiceInstallments->sum('amount');
|
||||||
|
|
||||||
|
// Remaining
|
||||||
|
$totalRemaining = max($totalPayable - $totalPaid, 0);
|
||||||
|
|
||||||
return view('admin.customers_view', compact(
|
return view('admin.customers_view', compact(
|
||||||
'customer',
|
'customer',
|
||||||
'totalOrders',
|
'totalOrders',
|
||||||
'totalAmount',
|
'totalOrderAmount',
|
||||||
'recentOrders'
|
'totalPayable',
|
||||||
|
'totalPaid',
|
||||||
|
'totalRemaining'
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// TOGGLE STATUS ACTIVE / INACTIVE
|
// TOGGLE STATUS ACTIVE / INACTIVE
|
||||||
|
|||||||
@@ -92,5 +92,20 @@ class Invoice extends Model
|
|||||||
return $this->hasMany(InvoiceInstallment::class);
|
return $this->hasMany(InvoiceInstallment::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// App\Models\Invoice.php
|
||||||
|
|
||||||
|
public function totalPaid()
|
||||||
|
{
|
||||||
|
return $this->installments()->sum('amount');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remainingAmount()
|
||||||
|
{
|
||||||
|
return max(
|
||||||
|
($this->final_amount_with_gst ?? 0) - $this->totalPaid(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,19 @@ public function invoices()
|
|||||||
return $this->hasMany(\App\Models\Invoice::class, 'customer_id', 'id');
|
return $this->hasMany(\App\Models\Invoice::class, 'customer_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// App\Models\User.php
|
||||||
|
|
||||||
|
|
||||||
|
public function invoiceInstallments()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(
|
||||||
|
InvoiceInstallment::class,
|
||||||
|
Invoice::class,
|
||||||
|
'customer_id', // FK on invoices
|
||||||
|
'invoice_id' // FK on installments
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'ttl' => (int) env('JWT_TTL', 15),
|
'ttl' => (int) env('JWT_TTL', 1440),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -108,7 +108,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'refresh_ttl' => (int) env('JWT_REFRESH_TTL', 60),
|
'refresh_ttl' => (int) env('JWT_REFRESH_TTL', 64800),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
public/invoices/invoice-INV-2025-000034.pdf
Normal file
BIN
public/invoices/invoice-INV-2025-000034.pdf
Normal file
Binary file not shown.
@@ -827,14 +827,29 @@
|
|||||||
<th class="table-header">Customer Info</th>
|
<th class="table-header">Customer Info</th>
|
||||||
<th class="table-header">Customer ID</th>
|
<th class="table-header">Customer ID</th>
|
||||||
<th class="table-header">Orders</th>
|
<th class="table-header">Orders</th>
|
||||||
<th class="table-header">Total</th>
|
<th class="table-header">Order Total</th>
|
||||||
|
<th class="table-header">Total Payable</th> {{-- NEW --}}
|
||||||
|
<th class="table-header">Remaining</th> {{-- NEW --}}
|
||||||
<th class="table-header">Create Date</th>
|
<th class="table-header">Create Date</th>
|
||||||
<th class="table-header">Status</th>
|
<th class="table-header">Status</th>
|
||||||
<th class="table-header" width="100">Actions</th>
|
<th class="table-header" width="100">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody id="customersTableBody">
|
<tbody id="customersTableBody">
|
||||||
@forelse($customers as $c)
|
@forelse($customers as $c)
|
||||||
|
@php
|
||||||
|
// Invoice total (with GST)
|
||||||
|
$totalPayable = $c->invoices->sum('final_amount_with_gst');
|
||||||
|
|
||||||
|
// Total paid via installments
|
||||||
|
$totalPaid = $c->invoices
|
||||||
|
->flatMap(fn($inv) => $inv->installments)
|
||||||
|
->sum('amount');
|
||||||
|
|
||||||
|
// Remaining amount
|
||||||
|
$remainingAmount = max($totalPayable - $totalPaid, 0);
|
||||||
|
@endphp
|
||||||
<tr>
|
<tr>
|
||||||
<!-- Customer Info Column -->
|
<!-- Customer Info Column -->
|
||||||
<td class="customer-info-column">
|
<td class="customer-info-column">
|
||||||
@@ -869,9 +884,33 @@
|
|||||||
|
|
||||||
<!-- Total Column -->
|
<!-- Total Column -->
|
||||||
<td class="total-column">
|
<td class="total-column">
|
||||||
<span class="total-amount">₹{{ number_format($c->orders->sum('ttl_amount'), 2) }}</span>
|
<span class="total-amount">
|
||||||
|
₹{{ number_format($c->orders->sum('ttl_amount'), 2) }}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td class="total-column">
|
||||||
|
<span class="total-amount">
|
||||||
|
₹{{ number_format($totalPayable, 2) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="total-column">
|
||||||
|
@if($remainingAmount > 0)
|
||||||
|
<span class="text-danger fw-bold">
|
||||||
|
₹{{ number_format($remainingAmount, 2) }}
|
||||||
|
</span>
|
||||||
|
@else
|
||||||
|
<span class="text-success fw-bold">
|
||||||
|
₹0.00
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Create Date -->
|
<!-- Create Date -->
|
||||||
<td class="create-date-column">
|
<td class="create-date-column">
|
||||||
<span class="text-muted">{{ $c->created_at ? $c->created_at->format('d-m-Y') : '-' }}</span>
|
<span class="text-muted">{{ $c->created_at ? $c->created_at->format('d-m-Y') : '-' }}</span>
|
||||||
|
|||||||
@@ -698,11 +698,48 @@
|
|||||||
<div class="stats-icon">
|
<div class="stats-icon">
|
||||||
<i class="bi bi-currency-rupee"></i>
|
<i class="bi bi-currency-rupee"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="stats-value">₹{{ number_format($totalAmount, 2) }}</div>
|
<div class="stats-value">₹{{ number_format($totalOrderAmount, 2) }}</div>
|
||||||
<div class="stats-label">Total Amount Spent</div>
|
<div class="stats-label">Total Amount Spent</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- {{-- Total Payable --}}
|
||||||
|
<div class="stats-card amount">
|
||||||
|
<div class="stats-icon">
|
||||||
|
<i class="bi bi-wallet2"></i>
|
||||||
|
</div>
|
||||||
|
<div class="stats-value">₹{{ number_format($totalPayable, 2) }}</div>
|
||||||
|
<div class="stats-label">Total Payable</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Total Remaining --}}
|
||||||
|
<div class="stats-card marks">
|
||||||
|
<div class="stats-icon">
|
||||||
|
<i class="bi bi-exclamation-circle"></i>
|
||||||
|
</div>
|
||||||
|
<div class="stats-value">₹{{ number_format($totalRemaining, 2) }}</div>
|
||||||
|
<div class="stats-label">Remaining Amount</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="col-md-4 animate-fade-in animation-delay-3">
|
||||||
|
<div class="stats-card marks">
|
||||||
|
<div class="stats-icon">
|
||||||
|
<i class="bi bi-hash"></i>
|
||||||
|
</div>
|
||||||
|
<div class="stats-value">₹{{ number_format($totalPayable, 2) }}</div>
|
||||||
|
<div class="stats-label">Total Payable</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 animate-fade-in animation-delay-3">
|
||||||
|
<div class="stats-card marks">
|
||||||
|
<div class="stats-icon">
|
||||||
|
<i class="bi bi-hash"></i>
|
||||||
|
</div>
|
||||||
|
<div class="stats-value">₹{{ number_format($totalRemaining, 2) }}</div>
|
||||||
|
<div class="stats-label">Remaining Amount</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{{-- Mark Count --}}
|
{{-- Mark Count --}}
|
||||||
<div class="col-md-4 animate-fade-in animation-delay-3">
|
<div class="col-md-4 animate-fade-in animation-delay-3">
|
||||||
<div class="stats-card marks">
|
<div class="stats-card marks">
|
||||||
|
|||||||
Reference in New Issue
Block a user