This commit is contained in:
Utkarsh Khedkar
2025-12-22 22:38:45 +05:30
9 changed files with 152 additions and 27 deletions

View File

@@ -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

View File

@@ -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
);
}
} }

View File

@@ -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
);
}
} }

View File

@@ -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.

View File

@@ -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>

View File

@@ -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">