From c381a0dc404161e8f1ceab81174768902be7790d Mon Sep 17 00:00:00 2001 From: Fahim Date: Tue, 10 Aug 2021 19:50:04 +0600 Subject: [PATCH] Updated: Charts & Helpers --- Modules/Setting/Entities/Setting.php | 2 + .../Http/Controllers/SettingController.php | 2 + app/Helpers/helpers.php | 37 ++++++- app/Http/Controllers/HomeController.php | 100 ++++++++++++++++-- public/js/chart-config.js | 75 +++++++++++++ public/mix-manifest.json | 1 + resources/js/chart-config.js | 91 ++++++++++++++++ resources/views/home.blade.php | 90 ++++------------ routes/web.php | 17 +-- webpack.mix.js | 1 + 10 files changed, 326 insertions(+), 90 deletions(-) create mode 100644 public/js/chart-config.js create mode 100644 resources/js/chart-config.js diff --git a/Modules/Setting/Entities/Setting.php b/Modules/Setting/Entities/Setting.php index f6f76c56..41ca34e8 100644 --- a/Modules/Setting/Entities/Setting.php +++ b/Modules/Setting/Entities/Setting.php @@ -12,6 +12,8 @@ class Setting extends Model protected $guarded = []; + protected $with = ['currency']; + public function currency() { return $this->belongsTo(Currency::class, 'default_currency_id', 'id'); } diff --git a/Modules/Setting/Http/Controllers/SettingController.php b/Modules/Setting/Http/Controllers/SettingController.php index 21b243fb..34603f34 100644 --- a/Modules/Setting/Http/Controllers/SettingController.php +++ b/Modules/Setting/Http/Controllers/SettingController.php @@ -45,6 +45,8 @@ class SettingController extends Controller 'footer_text' => $request->footer_text ]); + cache()->forget('settings'); + toast('Settings Updated!', 'info'); return redirect()->route('settings.index'); diff --git a/app/Helpers/helpers.php b/app/Helpers/helpers.php index 6bf60a0b..6a142283 100644 --- a/app/Helpers/helpers.php +++ b/app/Helpers/helpers.php @@ -2,7 +2,11 @@ if (!function_exists('settings')) { function settings() { - return \Modules\Setting\Entities\Setting::firstOrFail(); + $settings = cache()->remember('settings', 24*60, function () { + return \Modules\Setting\Entities\Setting::firstOrFail(); + }); + + return $settings; } } @@ -13,13 +17,38 @@ if (!function_exists('format_currency')) { } $settings = settings(); + $position = $settings->default_currency_position; + $symbol = $settings->currency->symbol; + $decimal_separator = $settings->currency->decimal_separator; + $thousand_separator = $settings->currency->thousand_separator; - if ($settings->default_currency_position == 'prefix') { - $formatted_value = $settings->currency->symbol . number_format((float) $value, 2, $settings->currency->decimal_separator, $settings->currency->thousand_separator); + if ($position == 'prefix') { + $formatted_value = $symbol . number_format((float) $value, 2, $decimal_separator, $thousand_separator); } else { - $formatted_value = number_format((float) $value, 2, $settings->currency->decimal_separator, $settings->currency->thousand_separator) . $settings->currency->symbol; + $formatted_value = number_format((float) $value, 2, $decimal_separator, $thousand_separator) . $symbol; } return $formatted_value; } } + +if (!function_exists('array_merge_numeric_values')) { + function array_merge_numeric_values() { + $arrays = func_get_args(); + $merged = array(); + foreach ($arrays as $array) { + foreach ($array as $key => $value) { + if (!is_numeric($value)) { + continue; + } + if (!isset($merged[$key])) { + $merged[$key] = $value; + } else { + $merged[$key] += $value; + } + } + } + + return $merged; + } +} diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index c84ba790..17d00e97 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -8,9 +8,13 @@ use Illuminate\Support\Facades\DB; use Modules\Expense\Entities\Expense; use Modules\Product\Entities\Product; use Modules\Purchase\Entities\Purchase; +use Modules\Purchase\Entities\PurchasePayment; use Modules\PurchasesReturn\Entities\PurchaseReturn; +use Modules\PurchasesReturn\Entities\PurchaseReturnPayment; use Modules\Sale\Entities\Sale; +use Modules\Sale\Entities\SalePayment; use Modules\SalesReturn\Entities\SaleReturn; +use Modules\SalesReturn\Entities\SaleReturnPayment; class HomeController extends Controller { @@ -40,6 +44,8 @@ class HomeController extends Controller public function currentMonthChart() { + abort_if(!request()->ajax(), 404); + $currentMonthSales = Sale::whereMonth('date', date('m')) ->whereYear('date', date('Y')) ->sum('total_amount') / 100; @@ -51,14 +57,16 @@ class HomeController extends Controller ->sum('amount') / 100; return response()->json([ - 'sales' => $currentMonthSales, + 'sales' => $currentMonthSales, 'purchases' => $currentMonthPurchases, - 'expenses' => $currentMonthExpenses + 'expenses' => $currentMonthExpenses ]); } public function salesPurchasesChart() { + abort_if(!request()->ajax(), 404); + $sales = $this->salesChartData(); $purchases = $this->purchasesChartData(); @@ -66,8 +74,84 @@ class HomeController extends Controller } + public function paymentChart() { + abort_if(!request()->ajax(), 404); + + $dates = collect(); + foreach (range(-11, 0) as $i) { + $date = Carbon::now()->addMonths($i)->format('m-Y'); + $dates->put($date, 0); + } + + $date_range = Carbon::today()->subYear()->format('Y-m-d'); + + $sale_payments = SalePayment::where('date', '>=', $date_range) + ->select([ + DB::raw("DATE_FORMAT(date, '%m-%Y') as month"), + DB::raw("SUM(amount) as amount") + ]) + ->groupBy('month')->orderBy('month') + ->get()->pluck('amount', 'month'); + + $sale_return_payments = SaleReturnPayment::where('date', '>=', $date_range) + ->select([ + DB::raw("DATE_FORMAT(date, '%m-%Y') as month"), + DB::raw("SUM(amount) as amount") + ]) + ->groupBy('month')->orderBy('month') + ->get()->pluck('amount', 'month'); + + $purchase_payments = PurchasePayment::where('date', '>=', $date_range) + ->select([ + DB::raw("DATE_FORMAT(date, '%m-%Y') as month"), + DB::raw("SUM(amount) as amount") + ]) + ->groupBy('month')->orderBy('month') + ->get()->pluck('amount', 'month'); + + $purchase_return_payments = PurchaseReturnPayment::where('date', '>=', $date_range) + ->select([ + DB::raw("DATE_FORMAT(date, '%m-%Y') as month"), + DB::raw("SUM(amount) as amount") + ]) + ->groupBy('month')->orderBy('month') + ->get()->pluck('amount', 'month'); + + $expenses = Expense::where('date', '>=', $date_range) + ->select([ + DB::raw("DATE_FORMAT(date, '%m-%Y') as month"), + DB::raw("SUM(amount) as amount") + ]) + ->groupBy('month')->orderBy('month') + ->get()->pluck('amount', 'month'); + + $payment_received = array_merge_numeric_values($sale_payments, $purchase_return_payments); + $payment_sent = array_merge_numeric_values($purchase_payments, $sale_return_payments, $expenses); + + $dates_received = $dates->merge($payment_received); + $dates_sent = $dates->merge($payment_sent); + + $received_payments = []; + $sent_payments = []; + $months = []; + + foreach ($dates_received as $key => $value) { + $received_payments[] = $value; + $months[] = $key; + } + + foreach ($dates_sent as $key => $value) { + $sent_payments[] = $value; + } + + return response()->json([ + 'payment_sent' => $sent_payments, + 'payment_received' => $received_payments, + 'months' => $months, + ]); + } + public function salesChartData() { - // Build an array of the dates we want to show, the oldest first $dates = collect(); foreach (range(-6, 0) as $i) { $date = Carbon::now()->addDays($i)->format('d-m-y'); @@ -75,17 +159,16 @@ class HomeController extends Controller } $date_range = Carbon::today()->subDays(6); - // Get the sales counts + $sales = Sale::where('date', '>=', $date_range) ->groupBy(DB::raw("DATE_FORMAT(date,'%d-%m-%y')")) - ->orderBy('date', 'asc') + ->orderBy('date') ->get([ DB::raw(DB::raw("DATE_FORMAT(date,'%d-%m-%y') as date")), DB::raw('SUM(total_amount) AS count'), ]) ->pluck('count', 'date'); - // Merge the two collections; $dates = $dates->merge($sales); $data = []; @@ -100,7 +183,6 @@ class HomeController extends Controller public function purchasesChartData() { - // Build an array of the dates we want to show, the oldest first $dates = collect(); foreach (range(-6, 0) as $i) { $date = Carbon::now()->addDays($i)->format('d-m-y'); @@ -109,17 +191,15 @@ class HomeController extends Controller $date_range = Carbon::today()->subDays(6); - // Get the purchases counts $purchases = Purchase::where('date', '>=', $date_range) ->groupBy(DB::raw("DATE_FORMAT(date,'%d-%m-%y')")) - ->orderBy('date', 'asc') + ->orderBy('date') ->get([ DB::raw(DB::raw("DATE_FORMAT(date,'%d-%m-%y') as date")), DB::raw('SUM(total_amount) AS count'), ]) ->pluck('count', 'date'); - // Merge the two collections; $dates = $dates->merge($purchases); $data = []; diff --git a/public/js/chart-config.js b/public/js/chart-config.js new file mode 100644 index 00000000..1ddbf1fe --- /dev/null +++ b/public/js/chart-config.js @@ -0,0 +1,75 @@ +/******/ (() => { // webpackBootstrap +var __webpack_exports__ = {}; +/*!**************************************!*\ + !*** ./resources/js/chart-config.js ***! + \**************************************/ +$(document).ready(function () { + var salesPurchasesBar = document.getElementById('salesPurchasesChart'); + $.get('/sales-purchases/chart-data', function (response) { + var salesPurchasesChart = new Chart(salesPurchasesBar, { + type: 'bar', + data: { + labels: response.sales.original.days, + datasets: [{ + label: 'Sales', + data: response.sales.original.data, + backgroundColor: ['#6366F1'], + borderColor: ['#6366F1'], + borderWidth: 1 + }, { + label: 'Purchases', + data: response.purchases.original.data, + backgroundColor: ['#A5B4FC'], + borderColor: ['#A5B4FC'], + borderWidth: 1 + }] + }, + options: { + scales: { + y: { + beginAtZero: true + } + } + } + }); + }); + var overviewChart = document.getElementById('currentMonthChart'); + $.get('/current-month/chart-data', function (response) { + var currentMonthChart = new Chart(overviewChart, { + type: 'doughnut', + data: { + labels: ['Sales', 'Purchases', 'Expenses'], + datasets: [{ + data: [response.sales, response.purchases, response.expenses], + backgroundColor: ['#F59E0B', '#0284C7', '#EF4444'], + hoverBackgroundColor: ['#F59E0B', '#0284C7', '#EF4444'] + }] + } + }); + }); + var paymentChart = document.getElementById('paymentChart'); + $.get('/payment-flow/chart-data', function (response) { + console.log(response); + var cashflowChart = new Chart(paymentChart, { + type: 'line', + data: { + labels: response.months, + datasets: [{ + label: 'Payment Sent', + data: response.payment_sent, + fill: false, + borderColor: '#EA580C', + tension: 0 + }, { + label: 'Payment Received', + data: response.payment_received, + fill: false, + borderColor: '#2563EB', + tension: 0 + }] + } + }); + }); +}); +/******/ })() +; \ No newline at end of file diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 2d601171..7dd9df61 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,4 +1,5 @@ { "/js/app.js": "/js/app.js", + "/js/chart-config.js": "/js/chart-config.js", "/css/app.css": "/css/app.css" } diff --git a/resources/js/chart-config.js b/resources/js/chart-config.js new file mode 100644 index 00000000..8e974b47 --- /dev/null +++ b/resources/js/chart-config.js @@ -0,0 +1,91 @@ +$(document).ready(function () { + let salesPurchasesBar = document.getElementById('salesPurchasesChart'); + $.get('/sales-purchases/chart-data', function (response) { + let salesPurchasesChart = new Chart(salesPurchasesBar, { + type: 'bar', + data: { + labels: response.sales.original.days, + datasets: [{ + label: 'Sales', + data: response.sales.original.data, + backgroundColor: [ + '#6366F1', + ], + borderColor: [ + '#6366F1', + ], + borderWidth: 1 + }, + { + label: 'Purchases', + data: response.purchases.original.data, + backgroundColor: [ + '#A5B4FC', + ], + borderColor: [ + '#A5B4FC', + ], + borderWidth: 1 + } + ] + }, + options: { + scales: { + y: { + beginAtZero: true + } + } + } + }); + }); + + let overviewChart = document.getElementById('currentMonthChart'); + $.get('/current-month/chart-data', function (response) { + let currentMonthChart = new Chart(overviewChart, { + type: 'doughnut', + data: { + labels: ['Sales', 'Purchases', 'Expenses'], + datasets: [{ + data: [response.sales, response.purchases, response.expenses], + backgroundColor: [ + '#F59E0B', + '#0284C7', + '#EF4444', + ], + hoverBackgroundColor: [ + '#F59E0B', + '#0284C7', + '#EF4444', + ], + }] + }, + }); + }); + + let paymentChart = document.getElementById('paymentChart'); + $.get('/payment-flow/chart-data', function (response) { + console.log(response) + let cashflowChart = new Chart(paymentChart, { + type: 'line', + data: { + labels: response.months, + datasets: [ + { + label: 'Payment Sent', + data: response.payment_sent, + fill: false, + borderColor: '#EA580C', + tension: 0 + }, + { + label: 'Payment Received', + data: response.payment_received, + fill: false, + borderColor: '#2563EB', + tension: 0 + }, + ] + }, + }); + }); +}); diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php index d0727b2c..39061c33 100644 --- a/resources/views/home.blade.php +++ b/resources/views/home.blade.php @@ -9,7 +9,7 @@ @endsection @section('content') -
+
@@ -68,7 +68,7 @@
-
+
@@ -82,10 +82,25 @@
- {{ now()->format('F, Y') }} + Overview of {{ now()->format('F, Y') }} +
+
+
+ +
+
+
+
+
+ +
+
+
+
+ Monthly Cash Flow (Payment Sent & Received)
- +
@@ -100,70 +115,5 @@ @endsection @push('page_scripts') - + @endpush diff --git a/routes/web.php b/routes/web.php index 07a99b6c..790f221e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,12 +14,17 @@ Route::get('/', function () { Auth::routes(); -Route::get('/home', 'HomeController@index') - ->name('home')->middleware('auth'); +Route::group(['middleware' => 'auth'], function () { + Route::get('/home', 'HomeController@index') + ->name('home'); -Route::get('/sales-purchases/chart-data', 'HomeController@salesPurchasesChart') - ->name('sales-purchases.chart')->middleware('auth'); + Route::get('/sales-purchases/chart-data', 'HomeController@salesPurchasesChart') + ->name('sales-purchases.chart'); -Route::get('/current-month/chart-data', 'HomeController@currentMonthChart') - ->name('current-month.chart')->middleware('auth'); + Route::get('/current-month/chart-data', 'HomeController@currentMonthChart') + ->name('current-month.chart'); + + Route::get('/payment-flow/chart-data', 'HomeController@paymentChart') + ->name('payment-flow.chart'); +}); diff --git a/webpack.mix.js b/webpack.mix.js index 8a923cbb..ebde44d7 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -12,4 +12,5 @@ const mix = require('laravel-mix'); */ mix.js('resources/js/app.js', 'public/js') + .js('resources/js/chart-config.js', 'public/js') .sass('resources/sass/app.scss', 'public/css');