diff --git a/app/Http/Controllers/Dashboard/Dashboard.php b/app/Http/Controllers/Dashboard/Dashboard.php index f401b3b19..14a769c05 100644 --- a/app/Http/Controllers/Dashboard/Dashboard.php +++ b/app/Http/Controllers/Dashboard/Dashboard.php @@ -21,6 +21,10 @@ class Dashboard extends Controller public $today; + public $income_donut = ['colors', 'labels', 'values']; + + public $expense_donut = ['colors', 'labels', 'values']; + /** * Display a listing of the resource. * @@ -29,134 +33,46 @@ class Dashboard extends Controller public function index() { $this->today = Date::today(); - $month_days = $this->today->daysInMonth; - /* - * Cash Flow - */ + list($total_incomes, $total_expenses, $total_profit) = $this->getTotals(); - // Daily - $day = array(); - $month_ago = $this->today->subMonth(); - for ($j = $month_days; $j > 0; $j--) { - $day[$month_days - $j] = $month_ago->addDay()->format('d M'); - } + $cashflow = $this->getCashFlow(); - $daily_income = $this->getCashFlow('income', 'daily'); - $daily_expense = $this->getCashFlow('expense', 'daily'); + list($donut_incomes, $donut_expenses) = $this->getDonuts(); - $daily_profit = $this->getProfit($daily_income, $daily_expense); + $accounts = Account::enabled()->get(); - // Monthly - $month = array(); - $year_ago = $this->today->subYear(); - for ($j = 12; $j >= 0; $j--) { - $month[12 - $j] = $year_ago->addMonth()->format('M Y'); - } + $latest_incomes = $this->getLatestIncomes(); - $monthly_income = $this->getCashFlow('income', 'monthly'); - $monthly_expense = $this->getCashFlow('expense', 'monthly'); + $latest_expenses = $this->getLatestExpenses(); - $monthly_profit = $this->getProfit($monthly_income, $monthly_expense); + return view('dashboard.dashboard.index', compact( + 'total_incomes', + 'total_expenses', + 'total_profit', + 'cashflow', + 'donut_incomes', + 'donut_expenses', + 'accounts', + 'latest_incomes', + 'latest_expenses' + )); + } - $line_daily = Charts::multi('line', 'chartjs') - ->dimensions(0, 300) - ->colors(['#6da252', '#00c0ef', '#F56954']) - ->dataset(trans_choice('general.profits', 1), $daily_profit) - ->dataset(trans_choice('general.incomes', 1), $daily_income) - ->dataset(trans_choice('general.expenses', 1), $daily_expense) - ->labels($day) - ->credits(false) - ->view('vendor.consoletvs.charts.chartjs.multi.line'); + public function cashFlow() + { + $this->today = Date::today(); - $line_monthly = Charts::multi('bar', 'chartjs') - ->dimensions(0, 300) - ->colors(['#6da252', '#00c0ef', '#F56954']) - ->dataset(trans_choice('general.profits', 1), $monthly_profit) - ->dataset(trans_choice('general.incomes', 1), $monthly_income) - ->dataset(trans_choice('general.expenses', 1), $monthly_expense) - ->labels($month) - ->credits(false); + $content = $this->getCashFlow()->render(); - /* - * Totals & Pie Charts - */ + //return response()->setContent($content)->send(); - $incomes = $expenses = array(); + echo $content; + } - $incomes_amount = $expenses_amount = 0; - - // Invoices - $invoices = Invoice::with('payments')->accrued()->get(); - list($invoice_paid_amount, $open_invoice, $overdue_invoice) = $this->getTotals($invoices, 'invoice'); - - $incomes_amount += $invoice_paid_amount; - - // Add to Incomes By Category - $donut_incomes_colors[] = '#00c0ef'; - $donut_incomes_labels[] = money($invoice_paid_amount, setting('general.default_currency'), true)->format() . ' - ' . trans_choice('general.invoices', 2); - $donut_incomes_values[] = (int) $invoice_paid_amount; - - // Bills - $bills = Bill::with('payments')->accrued()->get(); - list($bill_paid_amount, $open_bill, $overdue_bill) = $this->getTotals($bills, 'bill'); - - $expenses_amount += $bill_paid_amount; - - // Add to Expenses By Category - $donut_expenses_colors[] = '#dd4b39'; - $donut_expenses_labels[] = money($bill_paid_amount, setting('general.default_currency'), true)->format() . ' - ' . trans_choice('general.bills', 2); - $donut_expenses_values[] = (int) $bill_paid_amount; - - // Revenues & Payments - $categories = Category::orWhere('type', 'income')->orWhere('type', 'expense')->enabled()->get(); - - foreach ($categories as $category) { - switch ($category->type) { - case 'income': - $amount = 0; - - foreach ($category->revenues as $revenue) { - $amount += $revenue->getConvertedAmount(); - } - - $donut_incomes_colors[] = $category->color; - $donut_incomes_labels[] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $category->name; - $donut_incomes_values[] = (int) $amount; - - $incomes_amount += $amount; - break; - case 'expense': - $amount = 0; - - foreach ($category->payments as $payment) { - $amount += $payment->getConvertedAmount(); - } - - $donut_expenses_colors[] = $category->color; - $donut_expenses_labels[] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $category->name; - $donut_expenses_values[] = (int) $amount; - - $expenses_amount += $amount; - break; - } - } - - $donut_incomes = Charts::create('donut', 'chartjs') - ->colors($donut_incomes_colors) - ->labels($donut_incomes_labels) - ->values($donut_incomes_values) - ->dimensions(0, 160) - ->credits(false) - ->view('vendor.consoletvs.charts.chartjs.donut'); - - $donut_expenses = Charts::create('donut', 'chartjs') - ->colors($donut_expenses_colors) - ->labels($donut_expenses_labels) - ->values($donut_expenses_values) - ->dimensions(0, 160) - ->credits(false) - ->view('vendor.consoletvs.charts.chartjs.donut'); + private function getTotals() + { + list($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill) = $this->calculateAmounts(); $incomes_progress = 100; @@ -202,41 +118,145 @@ class Dashboard extends Controller 'progress' => $total_progress ); - /* - * Accounts - */ - - $accounts = Account::enabled()->get(); - - /* - * Latest Incomes - */ - - $latest_incomes = collect(Invoice::accrued()->latest()->take(10)->get()); - $latest_incomes = $latest_incomes->merge(Revenue::latest()->take(10)->get())->take(5)->sortByDesc('invoiced_at'); - - /* - * Latest Expenses - */ - - $latest_expenses = collect(Bill::accrued()->latest()->take(10)->get()); - $latest_expenses = $latest_expenses->merge(Payment::latest()->take(10)->get())->take(5)->sortByDesc('billed_at'); - - return view('dashboard.dashboard.index', compact( - 'total_incomes', - 'total_expenses', - 'total_profit', - 'line_daily', - 'line_monthly', - 'donut_incomes', - 'donut_expenses', - 'accounts', - 'latest_incomes', - 'latest_expenses' - )); + return array($total_incomes, $total_expenses, $total_profit); } - private function getCashFlow($type, $period) + private function getCashFlow() + { + $start = Date::parse(request('start', $this->today->startOfYear()->format('Y-m-d'))); + $end = Date::parse(request('end', $this->today->endOfYear()->format('Y-m-d'))); + $period = request('period', 'month'); + + $start_month = $start->month; + $end_month = $end->month; + + // Monthly + $labels = array(); + + $s = clone $start; + + for ($j = $end_month; $j >= $start_month; $j--) { + $labels[$end_month - $j] = $s->format('M Y'); + + if ($period == 'month') { + $s->addMonth(); + } else { + $s->addMonths(3); + $j -= 2; + } + } + + $income = $this->calculateCashFlowTotals('income', $start, $end, $period); + $expense = $this->calculateCashFlowTotals('expense', $start, $end, $period); + + $profit = $this->calculateCashFlowProfit($income, $expense); + + $chart = Charts::multi('bar', 'chartjs') + ->dimensions(0, 300) + ->colors(['#6da252', '#00c0ef', '#F56954']) + ->dataset(trans_choice('general.profits', 1), $profit) + ->dataset(trans_choice('general.incomes', 1), $income) + ->dataset(trans_choice('general.expenses', 1), $expense) + ->labels($labels) + ->credits(false) + ->view('vendor.consoletvs.charts.chartjs.multi.line'); + + return $chart; + } + + private function getDonuts() + { + $donut_incomes = Charts::create('donut', 'chartjs') + ->colors($this->income_donut['colors']) + ->labels($this->income_donut['labels']) + ->values($this->income_donut['values']) + ->dimensions(0, 160) + ->credits(false) + ->view('vendor.consoletvs.charts.chartjs.donut'); + + $donut_expenses = Charts::create('donut', 'chartjs') + ->colors($this->expense_donut['colors']) + ->labels($this->expense_donut['labels']) + ->values($this->expense_donut['values']) + ->dimensions(0, 160) + ->credits(false) + ->view('vendor.consoletvs.charts.chartjs.donut'); + + return array($donut_incomes, $donut_expenses); + } + + private function getLatestIncomes() + { + $latest = collect(Invoice::accrued()->latest()->take(10)->get()); + $latest = $latest->merge(Revenue::latest()->take(10)->get())->take(5)->sortByDesc('invoiced_at'); + + return $latest; + } + + private function getLatestExpenses() + { + $latest = collect(Bill::accrued()->latest()->take(10)->get()); + $latest = $latest->merge(Payment::latest()->take(10)->get())->take(5)->sortByDesc('billed_at'); + + return $latest; + } + + private function calculateAmounts() + { + $incomes_amount = $expenses_amount = 0; + + // Invoices + $invoices = Invoice::with('payments')->accrued()->get(); + list($invoice_paid_amount, $open_invoice, $overdue_invoice) = $this->calculateTotals($invoices, 'invoice'); + + $incomes_amount += $invoice_paid_amount; + + // Add to Incomes By Category + $this->addToIncomeDonut('#00c0ef', $invoice_paid_amount, trans_choice('general.invoices', 2)); + + // Bills + $bills = Bill::with('payments')->accrued()->get(); + list($bill_paid_amount, $open_bill, $overdue_bill) = $this->calculateTotals($bills, 'bill'); + + $expenses_amount += $bill_paid_amount; + + // Add to Expenses By Category + $this->addToExpenseDonut('#dd4b39', $bill_paid_amount, trans_choice('general.bills', 2)); + + // Revenues & Payments + $categories = Category::orWhere('type', 'income')->orWhere('type', 'expense')->enabled()->get(); + + foreach ($categories as $category) { + switch ($category->type) { + case 'income': + $amount = 0; + + foreach ($category->revenues as $revenue) { + $amount += $revenue->getConvertedAmount(); + } + + $this->addToIncomeDonut($category->color, $amount, $category->name); + + $incomes_amount += $amount; + break; + case 'expense': + $amount = 0; + + foreach ($category->payments as $payment) { + $amount += $payment->getConvertedAmount(); + } + + $this->addToExpenseDonut($category->color, $amount, $category->name); + + $expenses_amount += $amount; + break; + } + } + + return array($incomes_amount, $open_invoice, $overdue_invoice, $expenses_amount, $open_bill, $overdue_bill); + } + + private function calculateCashFlowTotals($type, $start, $end, $period) { $totals = array(); @@ -248,48 +268,30 @@ class Dashboard extends Controller $m2 = '\App\Models\Expense\BillPayment'; } - switch ($period) { - case 'yearly': - $f1 = 'subYear'; - $f2 = 'addYear'; + $date_format = 'Y-m'; - $date_format = 'Y'; - break; - case 'monthly': - $f1 = 'subYear'; - $f2 = 'addMonth'; - - $date_format = 'Y-m'; - break; - default: - case 'daily': - $f1 = 'subMonth'; - $f2 = 'addDay'; - - $date_format = 'Y-m-d'; - break; + $n = 1; + if ($period == 'quarter') { + $n = 3; } - $now = Date::now(); - $sub = Date::now()->$f1(); - - $start_date = $sub->format($date_format); - $end_date = $now->format($date_format); + $start_date = $start->format($date_format); + $end_date = $end->format($date_format); $next_date = $start_date; $totals[$start_date] = 0; do { - $next_date = Date::parse($next_date)->$f2()->format($date_format); + $next_date = Date::parse($next_date)->addMonths($n)->format($date_format); $totals[$next_date] = 0; } while ($next_date < $end_date); - $items_1 = $m1::whereBetween('paid_at', [$sub, $now])->get(); + $items_1 = $m1::whereBetween('paid_at', [$start, $end])->get(); $this->setCashFlowTotals($totals, $items_1, $date_format); - $items_2 = $m2::whereBetween('paid_at', [$sub, $now])->get(); + $items_2 = $m2::whereBetween('paid_at', [$start, $end])->get(); $this->setCashFlowTotals($totals, $items_2, $date_format); @@ -305,7 +307,22 @@ class Dashboard extends Controller } } - private function getTotals($items, $type) + private function calculateCashFlowProfit($incomes, $expenses) + { + $profit = []; + + foreach ($incomes as $key => $income) { + if ($income > 0 && $income > $expenses[$key]) { + $profit[$key] = $income - $expenses[$key]; + } else { + $profit[$key] = 0; + } + } + + return $profit; + } + + private function calculateTotals($items, $type) { $paid = $open = $overdue = 0; @@ -338,18 +355,22 @@ class Dashboard extends Controller return array($paid, $open, $overdue); } - private function getProfit($incomes, $expenses) + private function addToIncomeDonut($color, $amount, $text) { - $profit = []; + $this->addToDonut('income', $color, $amount, $text); + } - foreach ($incomes as $key => $income) { - if ($income > 0 && $income > $expenses[$key]) { - $profit[$key] = $income - $expenses[$key]; - } else { - $profit[$key] = 0; - } - } + private function addToExpenseDonut($color, $amount, $text) + { + $this->addToDonut('expense', $color, $amount, $text); + } - return $profit; + private function addToDonut($type, $color, $amount, $text) + { + $attribute = $type . '_donut'; + + $this->$attribute['colors'][] = $color; + $this->$attribute['labels'][] = money($amount, setting('general.default_currency'), true)->format() . ' - ' . $text; + $this->$attribute['values'][] = (int) $amount; } } diff --git a/resources/views/dashboard/dashboard/index.blade.php b/resources/views/dashboard/dashboard/index.blade.php index dd9d6542b..d086bcdc6 100644 --- a/resources/views/dashboard/dashboard/index.blade.php +++ b/resources/views/dashboard/dashboard/index.blade.php @@ -67,21 +67,23 @@
-