Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
DashboardMetricsService
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 4
20
0.00% covered (danger)
0.00%
0 / 1
 admin
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 influencer
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
2
 dailySales
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 hourlyUses
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Services;
4
5use App\Enums\CommissionStatus;
6use App\Enums\OrderStatus;
7use App\Models\Commission;
8use App\Models\Influencer;
9use App\Models\Order;
10use App\Models\Store;
11use Illuminate\Support\Facades\DB;
12
13class DashboardMetricsService
14{
15    public function admin(Store $store): array
16    {
17        return [
18            'influencers' => $store->influencers()->count(),
19            'orders_paid' => Order::where('store_id', $store->id)->where('status', OrderStatus::Paid->value)->count(),
20            'sales_amount' => (float) Order::where('store_id', $store->id)->where('status', OrderStatus::Paid->value)->sum('commission_base_amount'),
21            'forecasted_commission' => (float) Commission::where('store_id', $store->id)->where('status', CommissionStatus::Forecasted->value)->sum('commission_amount'),
22            'approved_commission' => (float) Commission::where('store_id', $store->id)->whereIn('status', [CommissionStatus::Approved, CommissionStatus::Released])->sum('commission_amount'),
23            'paid_commission' => (float) Commission::where('store_id', $store->id)->where('status', CommissionStatus::Paid->value)->sum('commission_amount'),
24        ];
25    }
26
27    public function influencer(Influencer $influencer): array
28    {
29        $monthQuery = Order::query()
30            ->where('influencer_id', $influencer->id)
31            ->whereMonth('placed_at', now()->month)
32            ->whereYear('placed_at', now()->year);
33
34        $paidOrders = (clone $monthQuery)->where('status', OrderStatus::Paid->value);
35
36        return [
37            'coupon_uses' => (clone $monthQuery)->whereNotNull('coupon_code_normalized')->count(),
38            'sales_paid' => (float) (clone $paidOrders)->sum('commission_base_amount'),
39            'orders_paid' => (clone $paidOrders)->count(),
40            'orders_pending' => (clone $monthQuery)->where('status', OrderStatus::Pending->value)->count(),
41            'orders_cancelled' => (clone $monthQuery)->whereIn('status', [OrderStatus::Cancelled, OrderStatus::Refunded])->count(),
42            'average_ticket' => (float) (clone $paidOrders)->avg('commission_base_amount'),
43            'commission_forecasted' => (float) Commission::where('influencer_id', $influencer->id)->where('status', CommissionStatus::Forecasted->value)->sum('commission_amount'),
44            'commission_approved' => (float) Commission::where('influencer_id', $influencer->id)->whereIn('status', [CommissionStatus::Approved, CommissionStatus::Released])->sum('commission_amount'),
45            'commission_paid' => (float) Commission::where('influencer_id', $influencer->id)->where('status', CommissionStatus::Paid->value)->sum('commission_amount'),
46            'daily_sales' => $this->dailySales($influencer),
47            'hourly_uses' => $this->hourlyUses($influencer),
48        ];
49    }
50
51    private function dailySales(Influencer $influencer): array
52    {
53        return Order::query()
54            ->selectRaw('DATE(paid_at) as label, SUM(commission_base_amount) as total')
55            ->where('influencer_id', $influencer->id)
56            ->where('status', OrderStatus::Paid->value)
57            ->whereMonth('paid_at', now()->month)
58            ->whereYear('paid_at', now()->year)
59            ->groupBy(DB::raw('DATE(paid_at)'))
60            ->orderBy('label')
61            ->pluck('total', 'label')
62            ->toArray();
63    }
64
65    private function hourlyUses(Influencer $influencer): array
66    {
67        return Order::query()
68            ->selectRaw('HOUR(placed_at) as label, COUNT(*) as total')
69            ->where('influencer_id', $influencer->id)
70            ->whereMonth('placed_at', now()->month)
71            ->whereYear('placed_at', now()->year)
72            ->groupBy(DB::raw('HOUR(placed_at)'))
73            ->orderBy('label')
74            ->pluck('total', 'label')
75            ->toArray();
76    }
77}