Page MenuHomePhorge

D1828.1775441991.diff
No OneTemporary

Authored By
Unknown
Size
9 KB
Referenced Files
None
Subscribers
None

D1828.1775441991.diff

diff --git a/src/app/Http/Controllers/API/V4/Admin/StatsController.php b/src/app/Http/Controllers/API/V4/Admin/StatsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/StatsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/StatsController.php
@@ -2,6 +2,7 @@
namespace App\Http\Controllers\API\V4\Admin;
+use App\Providers\PaymentProvider;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
@@ -15,6 +16,7 @@
public const COLOR_RED_DARK = '#a71d2a';
public const COLOR_BLUE = '#4da3ff'; // '#007bff'
public const COLOR_BLUE_DARK = '#0056b3';
+ public const COLOR_ORANGE = '#f1a539';
/**
* Fetch chart data
@@ -41,6 +43,122 @@
}
/**
+ * Get discounts chart
+ */
+ protected function chartDiscounts(): array
+ {
+ // TODO: Exclude deleted account wallets
+ $discounts = DB::table('wallets')
+ ->join('discounts', 'discounts.id', '=', 'wallets.discount_id')
+ ->selectRaw("discount, count(discount_id) as cnt")
+ ->groupBy('discounts.discount')
+ ->get()
+ ->pluck('cnt', 'discount')
+ ->all();
+
+ $labels = array_keys($discounts);
+ $discounts = array_values($discounts);
+
+ // $labels = [10, 25, 30, 100];
+ // $discounts = [100, 120, 30, 50];
+
+ $labels = array_map(function ($item) {
+ return $item . '%';
+ }, $labels);
+
+ // See https://frappe.io/charts/docs for format/options description
+
+ return [
+ 'title' => 'Discounts',
+ 'type' => 'donut',
+ 'colors' => [
+ self::COLOR_BLUE,
+ self::COLOR_BLUE_DARK,
+ self::COLOR_GREEN,
+ self::COLOR_GREEN_DARK,
+ self::COLOR_ORANGE,
+ self::COLOR_RED,
+ self::COLOR_RED_DARK
+ ],
+ 'maxSlices' => 8,
+ 'tooltipOptions' => [], // does not work without it (https://github.com/frappe/charts/issues/314)
+ 'data' => [
+ 'labels' => $labels,
+ 'datasets' => [
+ [
+ 'values' => $discounts
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Get income chart
+ */
+ protected function chartIncome(): array
+ {
+ $weeks = 8;
+ $start = Carbon::now();
+ $labels = [];
+
+ while ($weeks > 0) {
+ $labels[] = $start->format('Y-W');
+ $start->subWeeks(1);
+ $weeks--;
+ }
+
+ $labels = array_reverse($labels);
+ $start->startOfWeek(Carbon::MONDAY);
+
+ $payments = DB::table('payments')
+ ->selectRaw("concat(year(updated_at), '-', week(updated_at, 3)) as period, sum(amount) as amount")
+ ->where('updated_at', '>=', $start->toDateString())
+ ->where('status', PaymentProvider::STATUS_PAID)
+ ->whereIn('type', [PaymentProvider::TYPE_ONEOFF, PaymentProvider::TYPE_RECURRING])
+ ->groupByRaw('1')
+ ->get()
+ ->pluck('amount', 'period')
+ ->map(function ($amount) {
+ return $amount / 100;
+ });
+
+ // TODO: exclude refunds/chargebacks
+
+ $empty = array_fill_keys($labels, 0);
+ $payments = array_values(array_merge($empty, $payments->all()));
+
+ // $payments = [1000, 1200.25, 3000, 1897.50, 2000, 1900, 2134, 3330];
+
+ // See https://frappe.io/charts/docs for format/options description
+
+ return [
+ 'title' => 'Income in CHF - last 8 weeks',
+ 'type' => 'bar',
+ 'colors' => [self::COLOR_BLUE],
+ 'axisOptions' => [
+ 'xIsSeries' => true,
+ ],
+ 'data' => [
+ 'labels' => $labels,
+ 'datasets' => [
+ [
+ // 'name' => 'Payments',
+ 'values' => $payments
+ ]
+ ],
+ 'yMarkers' => [
+ [
+ 'label' => 'average',
+ 'value' => collect($payments)->avg(),
+ 'options' => [ 'labelPos' => 'left' ] // default: 'right'
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
* Get created/deleted users chart
*/
protected function chartUsers(): array
@@ -71,11 +189,11 @@
->get();
$empty = array_fill_keys($labels, 0);
- $created = array_merge($empty, $created->pluck('cnt', 'period')->all());
- $deleted = array_merge($empty, $deleted->pluck('cnt', 'period')->all());
+ $created = array_values(array_merge($empty, $created->pluck('cnt', 'period')->all()));
+ $deleted = array_values(array_merge($empty, $deleted->pluck('cnt', 'period')->all()));
- //$created = [5, 2, 4, 2, 0, 5, 2, 4];
- //$deleted = [1, 2, 3, 1, 2, 1, 2, 3];
+ // $created = [5, 2, 4, 2, 0, 5, 2, 4];
+ // $deleted = [1, 2, 3, 1, 2, 1, 2, 3];
// See https://frappe.io/charts/docs for format/options description
@@ -83,6 +201,9 @@
'title' => 'Users - last 8 weeks',
// 'type' => 'axis-mixed',
'colors' => [self::COLOR_GREEN, self::COLOR_RED],
+ 'axisOptions' => [
+ 'xIsSeries' => true,
+ ],
'data' => [
'labels' => $labels,
'datasets' => [
@@ -96,6 +217,89 @@
'chartType' => 'line',
'values' => $deleted
]
+ ],
+ 'yMarkers' => [
+ [
+ 'label' => 'average',
+ 'value' => collect($created)->avg(),
+ 'options' => [ 'labelPos' => 'left' ] // default: 'right'
+ ]
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Get all users chart
+ */
+ protected function chartUsersAll(): array
+ {
+ $weeks = 54;
+ $start = Carbon::now();
+ $labels = [];
+
+ while ($weeks > 0) {
+ $labels[] = $start->format('Y-W');
+ $start->subWeeks(1);
+ $weeks--;
+ }
+
+ $labels = array_reverse($labels);
+ $start->startOfWeek(Carbon::MONDAY);
+
+ $created = DB::table('users')
+ ->selectRaw("concat(year(created_at), '-', week(created_at, 3)) as period, count(*) as cnt")
+ ->where('created_at', '>=', $start->toDateString())
+ ->groupByRaw('1')
+ ->get();
+
+ $deleted = DB::table('users')
+ ->selectRaw("concat(year(deleted_at), '-', week(deleted_at, 3)) as period, count(*) as cnt")
+ ->where('deleted_at', '>=', $start->toDateString())
+ ->groupByRaw('1')
+ ->get();
+
+ $count = DB::table('users')->whereNull('deleted_at')->count();
+
+ $empty = array_fill_keys($labels, 0);
+ $created = array_merge($empty, $created->pluck('cnt', 'period')->all());
+ $deleted = array_merge($empty, $deleted->pluck('cnt', 'period')->all());
+ $all = [];
+
+ foreach (array_reverse($labels) as $label) {
+ $diff = $created[$label] - $deleted[$label];
+ $all[] = $count - $created[$label];
+ $count -= $diff;
+ }
+
+ $all = array_reverse($all);
+
+ // $start = 3000;
+ // for ($i = 0; $i < count($labels); $i++) {
+ // $all[$i] = $start + $i * 15;
+ // }
+
+ // See https://frappe.io/charts/docs for format/options description
+
+ return [
+ 'title' => 'All Users - last year',
+ 'type' => 'line',
+ 'colors' => [self::COLOR_GREEN],
+ 'axisOptions' => [
+ 'xIsSeries' => true,
+ 'xAxisMode' => 'tick',
+ ],
+ 'lineOptions' => [
+ 'hideDots' => true,
+ 'regionFill' => true,
+ ],
+ 'data' => [
+ 'labels' => $labels,
+ 'datasets' => [
+ [
+ // 'name' => 'Existing',
+ 'values' => $all
+ ]
]
]
];
diff --git a/src/resources/themes/charts.scss b/src/resources/themes/charts.scss
--- a/src/resources/themes/charts.scss
+++ b/src/resources/themes/charts.scss
@@ -14,6 +14,28 @@
border: 1px solid lightgrey;
border-radius: 0.5em;
padding-top: 0.5em;
+ margin: 0.5em;
min-height: 250px;
+ text-align: center;
+
+ & > span {
+ line-height: 240px;
+ }
}
-}
\ No newline at end of file
+}
+
+@include media-breakpoint-up(lg) {
+ #stats-container {
+ display: flex;
+ flex-wrap: wrap;
+ align-content: baseline;
+
+ & > div {
+ width: calc(50% - 1em);
+
+ svg {
+ width: 100%;
+ }
+ }
+ }
+}
diff --git a/src/resources/vue/Admin/Stats.vue b/src/resources/vue/Admin/Stats.vue
--- a/src/resources/vue/Admin/Stats.vue
+++ b/src/resources/vue/Admin/Stats.vue
@@ -13,7 +13,7 @@
}
},
mounted() {
- this.loadChart('users')
+ ['users', 'users-all', 'income', 'discounts'].forEach(chart => this.loadChart(chart))
},
methods: {
drawChart(name, data) {
@@ -35,6 +35,11 @@
this.$root.removeLoader(chart)
this.drawChart(name, response.data)
})
+ .catch(error => {
+ console.error(error)
+ this.$root.removeLoader(chart)
+ chart.append($('<span>').text('Failed to load data.'))
+ })
}
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 2:19 AM (23 h, 7 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18773382
Default Alt Text
D1828.1775441991.diff (9 KB)

Event Timeline