@php
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Lead;
use App\Models\Proposal;
use App\Models\Estimation;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
// Date Range
$fromDate = request('from_date') ? Carbon::parse(request('from_date'))->startOfDay() : Carbon::now()->startOfMonth();
$toDate = request('to_date') ? Carbon::parse(request('to_date'))->endOfDay() : Carbon::now()->endOfDay();
$dateRange = [
'from' => $fromDate->format('Y-m-d'),
'to' => $toDate->format('Y-m-d'),
];
// Helper function
function formatCurrencyDash($amount, $symbol = '₹') {
$amount = $amount ?? 0;
if ($amount >= 10000000) return $symbol . number_format($amount / 10000000, 2) . ' Cr';
if ($amount >= 100000) return $symbol . number_format($amount / 100000, 2) . ' L';
if ($amount >= 1000) return $symbol . number_format($amount / 1000, 2) . ' K';
return $symbol . number_format($amount, 2);
}
// Revenue Stats
$totalRevenue = Invoice::where('payment_status', 'paid')->sum('total') ?? 0;
$periodRevenue = Invoice::where('payment_status', 'paid')
->whereBetween('created_at', [$fromDate, $toDate])
->sum('total') ?? 0;
$periodDays = $fromDate->diffInDays($toDate);
$prevFromDate = (clone $fromDate)->subDays($periodDays + 1);
$prevToDate = (clone $fromDate)->subDay();
$prevPeriodRevenue = Invoice::where('payment_status', 'paid')
->whereBetween('created_at', [$prevFromDate, $prevToDate])
->sum('total') ?? 0;
$revenueGrowth = $prevPeriodRevenue > 0 ? round((($periodRevenue - $prevPeriodRevenue) / $prevPeriodRevenue) * 100, 1) : ($periodRevenue > 0 ? 100 : 0);
// Customer Stats
$totalCustomers = Customer::where('active', 1)->count();
$newCustomers = Customer::whereBetween('created_at', [$fromDate, $toDate])->count();
$companyCustomers = Customer::where('customer_type', 'company')->where('active', 1)->count();
$individualCustomers = Customer::where('customer_type', 'individual')->where('active', 1)->count();
// Invoice Stats
$pendingAmount = Invoice::whereIn('payment_status', ['unpaid', 'partial'])->sum('amount_due') ?? 0;
$pendingCount = Invoice::whereIn('payment_status', ['unpaid', 'partial'])->count();
$overdueCount = Invoice::where('due_date', '<', Carbon::now())->whereIn('payment_status', ['unpaid', 'partial'])->count();
$overdueAmount = Invoice::where('due_date', '<', Carbon::now())->whereIn('payment_status', ['unpaid', 'partial'])->sum('amount_due') ?? 0;
$paidCount = Invoice::where('payment_status', 'paid')->count();
$partialCount = Invoice::where('payment_status', 'partial')->count();
$unpaidCount = Invoice::where('payment_status', 'unpaid')->count();
// Lead Stats
$openLeads = Lead::where('lost', 0)->where('junk', 0)->count();
$newLeads = Lead::whereBetween('created_at', [$fromDate, $toDate])->count();
$totalLeadValue = Lead::where('lost', 0)->where('junk', 0)->sum('lead_value') ?? 0;
$lostLeads = Lead::where('lost', 1)->count();
$junkLeads = Lead::where('junk', 1)->count();
$convertedLeads = Lead::whereBetween('date_converted', [$fromDate, $toDate])->count();
// Proposal Stats
$totalProposals = Proposal::count();
$acceptedProposals = Proposal::where('status', 'accepted')->count();
$draftProposals = Proposal::where('status', 'draft')->count();
$sentProposals = Proposal::where('status', 'sent')->count();
// Estimation Stats
$totalEstimations = Estimation::count();
$approvedEstimations = Estimation::where('status', 'approved')->count();
$draftEstimations = Estimation::where('status', 'draft')->count();
// Chart Data - Revenue Trend
$days = $fromDate->diffInDays($toDate);
$revenueTrendLabels = [];
$revenueTrendValues = [];
if ($days <= 31) {
$revenueData = Invoice::where('payment_status', 'paid')
->whereBetween('created_at', [$fromDate, $toDate])
->selectRaw('DATE(created_at) as date, SUM(total) as total')
->groupByRaw('DATE(created_at)')
->orderByRaw('DATE(created_at)')
->pluck('total', 'date')
->toArray();
$current = clone $fromDate;
while ($current <= $toDate) {
$dateStr = $current->format('Y-m-d');
$revenueTrendLabels[] = $current->format('d M');
$revenueTrendValues[] = (float)($revenueData[$dateStr] ?? 0);
$current->addDay();
}
} else {
$revenueData = Invoice::where('payment_status', 'paid')
->whereBetween('created_at', [$fromDate, $toDate])
->selectRaw('YEAR(created_at) as year, MONTH(created_at) as month, SUM(total) as total')
->groupByRaw('YEAR(created_at), MONTH(created_at)')
->orderByRaw('YEAR(created_at), MONTH(created_at)')
->get();
foreach ($revenueData as $row) {
$revenueTrendLabels[] = Carbon::create($row->year, $row->month, 1)->format('M Y');
$revenueTrendValues[] = (float)$row->total;
}
}
// Chart Data - Invoice Status
$invoiceStatusLabels = ['Paid', 'Partial', 'Unpaid', 'Overdue'];
$invoiceStatusValues = [$paidCount, $partialCount, $unpaidCount, $overdueCount];
$invoiceStatusColors = ['#10b981', '#f59e0b', '#6b7280', '#ef4444'];
// Chart Data - Lead Status (WITH STATUS IDS FOR CLICK FILTERING)
$leadStatuses = DB::table('leads')
->join('leads_status', 'leads.status', '=', 'leads_status.id')
->where('leads.lost', 0)
->where('leads.junk', 0)
->select('leads_status.id', 'leads_status.name', 'leads_status.color', DB::raw('COUNT(*) as count'))
->groupBy('leads_status.id', 'leads_status.name', 'leads_status.color')
->get();
$leadStatusLabels = $leadStatuses->pluck('name')->toArray();
$leadStatusValues = $leadStatuses->pluck('count')->toArray();
$leadStatusColors = $leadStatuses->pluck('color')->map(fn($c) => $c ?? '#3498db')->toArray();
$leadStatusIds = $leadStatuses->pluck('id')->toArray(); // Status IDs for click filtering
// Add Lost and Junk to chart data
if ($lostLeads > 0) {
$leadStatusLabels[] = 'Lost';
$leadStatusValues[] = $lostLeads;
$leadStatusColors[] = '#e74c3c';
$leadStatusIds[] = 'lost'; // Special identifier for lost
}
if ($junkLeads > 0) {
$leadStatusLabels[] = 'Junk';
$leadStatusValues[] = $junkLeads;
$leadStatusColors[] = '#95a5a6';
$leadStatusIds[] = 'junk'; // Special identifier for junk
}
// Chart Data - Customer Growth
$customerGrowthLabels = [];
$customerGrowthValues = [];
for ($i = 5; $i >= 0; $i--) {
$date = Carbon::now()->subMonths($i);
$customerGrowthLabels[] = $date->format('M Y');
$customerGrowthValues[] = Customer::whereYear('created_at', $date->year)->whereMonth('created_at', $date->month)->count();
}
// Monthly Comparison
$currentMonth = Carbon::now();
$lastMonth = Carbon::now()->subMonth();
$currentMonthData = [
'label' => $currentMonth->format('M Y'),
'revenue' => Invoice::where('payment_status', 'paid')->whereMonth('created_at', $currentMonth->month)->whereYear('created_at', $currentMonth->year)->sum('total') ?? 0,
'invoices' => Invoice::whereMonth('created_at', $currentMonth->month)->whereYear('created_at', $currentMonth->year)->count(),
'customers' => Customer::whereMonth('created_at', $currentMonth->month)->whereYear('created_at', $currentMonth->year)->count(),
'leads' => Lead::whereMonth('created_at', $currentMonth->month)->whereYear('created_at', $currentMonth->year)->count(),
];
$lastMonthData = [
'label' => $lastMonth->format('M Y'),
'revenue' => Invoice::where('payment_status', 'paid')->whereMonth('created_at', $lastMonth->month)->whereYear('created_at', $lastMonth->year)->sum('total') ?? 0,
'invoices' => Invoice::whereMonth('created_at', $lastMonth->month)->whereYear('created_at', $lastMonth->year)->count(),
'customers' => Customer::whereMonth('created_at', $lastMonth->month)->whereYear('created_at', $lastMonth->year)->count(),
'leads' => Lead::whereMonth('created_at', $lastMonth->month)->whereYear('created_at', $lastMonth->year)->count(),
];
// Recent Data
$recentInvoices = Invoice::with('customer')->latest()->take(5)->get();
$recentCustomers = Customer::latest()->take(5)->get();
$recentLeads = Lead::with(['leadStatus', 'leadSource'])->where('lost', 0)->where('junk', 0)->latest()->take(5)->get();
@endphp
Dashboard
{{-- Date Range Filter --}}
Showing data from {{ Carbon::parse($dateRange['from'])->format('d M Y') }} to {{ Carbon::parse($dateRange['to'])->format('d M Y') }}
Period Revenue
{{ formatCurrencyDash($periodRevenue) }}
Total: {{ formatCurrencyDash($totalRevenue) }}
Total Customers
{{ number_format($totalCustomers) }}
{{ $companyCustomers }} Companies • {{ $individualCustomers }} Individuals
Pending Amount
{{ formatCurrencyDash($pendingAmount) }}
{{ $overdueCount }} overdue ({{ formatCurrencyDash($overdueAmount) }})
Open Leads
{{ number_format($openLeads) }}
Pipeline: {{ formatCurrencyDash($totalLeadValue) }}
Revenue
{{ $currentMonthData['label'] }}
₹{{ number_format($currentMonthData['revenue'], 2) }}
{{ $lastMonthData['label'] }}
₹{{ number_format($lastMonthData['revenue'], 2) }}
Invoices Created
{{ $currentMonthData['label'] }}
{{ $currentMonthData['invoices'] }}
{{ $lastMonthData['label'] }}
{{ $lastMonthData['invoices'] }}
New Customers
{{ $currentMonthData['label'] }}
{{ $currentMonthData['customers'] }}
{{ $lastMonthData['label'] }}
{{ $lastMonthData['customers'] }}
New Leads
{{ $currentMonthData['label'] }}
{{ $currentMonthData['leads'] }}
{{ $lastMonthData['label'] }}
{{ $lastMonthData['leads'] }}
|
{{ $invoice->invoice_number }} {{ $invoice->customer->name ?? $invoice->customer->company ?? 'N/A' }} |
{{ formatCurrencyDash($invoice->total) }} @if($invoice->payment_status === 'paid') Paid @elseif($invoice->payment_status === 'partial') Partial @elseif($invoice->due_date && $invoice->due_date < now()) Overdue @else {{ ucfirst($invoice->payment_status) }} @endif |
No invoices yet
|
{{ strtoupper(substr($customer->name ?? 'C', 0, 1)) }}
{{ $customer->display_name }} {{ $customer->email ?? '-' }} |
@if($customer->customer_type === 'company') Company @else Individual @endif |
No customers yet
|
{{ $lead->name }} {{ $lead->company ?? $lead->email ?? '-' }} |
{{ formatCurrencyDash($lead->lead_value ?? 0) }} {{ $lead->leadStatus->name ?? '-' }} |
No leads yet