diff --git a/app/Http/Controllers/Customers/Dashboard.php b/app/Http/Controllers/Customers/Dashboard.php index bdf575272..ac3014bcf 100644 --- a/app/Http/Controllers/Customers/Dashboard.php +++ b/app/Http/Controllers/Customers/Dashboard.php @@ -4,10 +4,11 @@ namespace App\Http\Controllers\Customers; use App\Http\Controllers\Controller; use App\Models\Income\Invoice; +use Charts; +use Date; class Dashboard extends Controller { - /** * Display a listing of the resource. * @@ -19,6 +20,106 @@ class Dashboard extends Controller $invoices = Invoice::with('status')->accrued()->where('customer_id', $customer->id)->get(); - return view('customers.dashboard.index', compact('customer', 'invoices')); + $start = Date::parse(request('start', Date::today()->startOfYear()->format('Y-m-d'))); + $end = Date::parse(request('end', Date::today()->endOfYear()->format('Y-m-d'))); + + $start_month = $start->month; + $end_month = $end->month; + + // Monthly + $labels = []; + + $s = clone $start; + + for ($j = $end_month; $j >= $start_month; $j--) { + $labels[$end_month - $j] = $s->format('M Y'); + + $s->addMonth(); + } + + $unpaid = $paid = $overdue = $partial_paid = []; + + foreach ($invoices as $invoice) { + switch ($invoice->invoice_status_code) { + case 'paid': + $paid[] = $invoice; + break; + case 'partial': + $partial_paid[] = $invoice; + break; + case 'sent': + default: + if (Date::today()->format('Y-m-d') > $invoice->due_at->format('Y-m-d')) { + $overdue[] = $invoice; + } else { + $unpaid[] = $invoice; + } + } + } + + $total = count($unpaid) + count($paid) + count($partial_paid) + count($overdue); + + $progress = [ + 'unpaid' => count($unpaid), + 'paid' => count($paid), + 'overdue' => count($overdue), + 'partially_paid' => count($partial_paid), + 'total' => $total, + ]; + + $unpaid = $this->calculateTotals($unpaid, $start, $end, 'unpaid'); + $paid = $this->calculateTotals($paid, $start, $end, 'paid'); + $partial_paid = $this->calculateTotals($partial_paid, $start, $end, 'partial'); + $overdue = $this->calculateTotals($overdue, $start, $end, 'overdue'); + + $chart = Charts::multi('line', 'chartjs') + ->dimensions(0, 300) + ->colors(['#dd4b39', '#6da252', '#f39c12', '#00c0ef']) + ->dataset(trans('general.unpaid'), $unpaid) + ->dataset(trans('general.paid'), $paid) + ->dataset(trans('general.overdue'), $overdue) + ->dataset(trans('general.partially_paid'), $partial_paid) + ->labels($labels) + ->credits(false) + ->view('vendor.consoletvs.charts.chartjs.multi.line'); + + return view('customers.dashboard.index', compact('customer', 'invoices', 'progress', 'chart')); + } + + private function calculateTotals($items, $start, $end, $type) + { + $totals = []; + + $date_format = 'Y-m'; + + $n = 1; + $start_date = $start->format($date_format); + $end_date = $end->format($date_format); + $next_date = $start_date; + + $s = clone $start; + + while ($next_date <= $end_date) { + $totals[$next_date] = 0; + + $next_date = $s->addMonths($n)->format($date_format); + } + + $this->setTotals($totals, $items, $date_format, $type); + + return $totals; + } + + private function setTotals(&$totals, $items, $date_format, $type) + { + foreach ($items as $item) { + if ($type == 'partial') { + $item->amount = $item->payments()->paid(); + } + + $i = Date::parse($item->paid_at)->format($date_format); + + $totals[$i] += $item->getConvertedAmount(); + } } } diff --git a/public/css/app.css b/public/css/app.css index cb55b99af..bf6ae27d2 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -521,4 +521,17 @@ ul.add-new.nav.navbar-nav.pull-left { position: fixed; right: 0; z-index: 999; -}*/ \ No newline at end of file +}*/ +.progress-bar-green, .progress-bar-success { + background-color: #6da252; +} + +#chart .row { + margin-top: 10px; +} + +#chart .row .col-md-3 .customer-content .progress { + clear: both; + margin-top: 25px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index e01c7aa6f..f699e91c9 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -93,6 +93,11 @@ return [ 'id' => 'ID', 'more_actions' => 'More Actions', 'duplicate' => 'Duplicate', + 'unpaid' => 'Unpaid', + 'paid' => 'Paid', + 'overdue' => 'Overdue', + 'partially' => 'Partially', + 'partially_paid' => 'Partially Paid', 'title' => [ 'new' => 'New :type', diff --git a/resources/views/customers/dashboard/index.blade.php b/resources/views/customers/dashboard/index.blade.php index 8ac2a9d47..cbb374b0f 100644 --- a/resources/views/customers/dashboard/index.blade.php +++ b/resources/views/customers/dashboard/index.blade.php @@ -4,90 +4,63 @@ @section('content')
+
-
-
-

{{ trans_choice('general.invoices', 2) }}

-
- - +
+
+
+
+
{{ trans('general.unpaid') }}
+
{{ $progress['total'] }} / {{ $progress['unpaid'] }}
+
+
+ {{ (100 / $progress['total']) * $progress['unpaid'] }} % +
+
+
+
+
+
+
{{ trans('general.paid') }}
+
{{ $progress['total'] }} / {{ $progress['paid'] }}
+
+
+ {{ (100 / $progress['total']) * $progress['paid'] }}% +
+
+
+
+
+
+
{{ trans('general.overdue') }}
+
{{ $progress['total'] }} / {{ $progress['overdue'] }}
+
+
+ {{ (100 / $progress['total']) * $progress['overdue'] }}% +
+
+
+
+
+
+
{{ trans('general.partially_paid') }}
+
{{ $progress['total'] }} / {{ $progress['partially_paid'] }}
+
+
+ {{ (100 / $progress['total']) * $progress['partially_paid'] }}% +
+
+
+
-
-
- @if ($invoices->count()) - - - - - - - - - - - - @foreach($invoices as $item) - - - - - - - - @endforeach - -
{{ trans('invoices.invoice_number') }}{{ trans('general.amount') }}{{ trans('invoices.invoice_date') }}{{ trans('invoices.due_date') }}{{ trans_choice('general.statuses', 1) }}
{{ $item->invoice_number }}@money($item->amount, $item->currency_code, true){{ Date::parse($item->invoiced_at)->format($date_format) }}{{ Date::parse($item->due_at)->format($date_format) }}{{ $item->status->name }}
- @else -
{{ trans('general.no_records') }}
- @endif +
+ {!! $chart->render() !!}
- -
-
- -
-
-

{{ trans_choice('general.payments', 2) }}

-
- - -
-
-
- @if ($customer->revenues->count()) - - - - - - - - - - - @foreach($customer->revenues as $item) - - - - - - - @endforeach - -
{{ trans('general.date') }}{{ trans('general.amount') }}{{ trans_choice('general.categories', 1) }}{{ trans_choice('general.accounts', 1) }}
{{ Date::parse($item->paid_at)->format($date_format) }}@money($item->amount, $item->currency_code, true){{ $item->category->name }}{{ $item->account->name }}
- @else -
{{ trans('general.no_records') }}
- @endif -
-
-
-
-@endsection \ No newline at end of file +@endsection +@push('js') +{!! Charts::assets() !!} +@endpush \ No newline at end of file