Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
SalesByPaymentMethodReport
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
7 / 7
7
100.00% covered (success)
100.00%
1 / 1
 key
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 label
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 group
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 description
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 columns
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 rows
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 summary
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Reports\Sales;
4
5use App\Models\Order;
6use App\Models\Payment;
7use App\Reports\Report;
8use Illuminate\Support\Collection;
9
10/** Every order without a gateway Payment row is Cash on Delivery — that's the one method that never posts to `payments`. */
11class SalesByPaymentMethodReport extends Report
12{
13    public function key(): string
14    {
15        return 'sales-by-payment-method';
16    }
17
18    public function label(): string
19    {
20        return 'Sales by Payment Method';
21    }
22
23    public function group(): string
24    {
25        return 'Sales';
26    }
27
28    public function description(): ?string
29    {
30        return 'Order count and revenue per payment method, Cash on Delivery included.';
31    }
32
33    public function columns(): array
34    {
35        return [
36            ['key' => 'method', 'label' => 'Payment Method'],
37            ['key' => 'orders', 'label' => 'Orders', 'align' => 'right'],
38            ['key' => 'revenue', 'label' => 'Revenue', 'align' => 'right', 'render' => fn ($r) => money($r->revenue)],
39        ];
40    }
41
42    public function rows(array $filters): Collection
43    {
44        $orders = Order::query()
45            ->whereDate('created_at', '>=', $filters['from'])
46            ->whereDate('created_at', '<=', $filters['to'])
47            ->get(['id', 'total']);
48
49        $methods = Payment::whereIn('order_id', $orders->pluck('id'))->pluck('payment_type', 'order_id');
50
51        return $orders->groupBy(fn ($o) => $methods[$o->id] ?? 'cod')
52            ->map(fn ($group, $method) => (object) [
53                'method' => ucfirst(str_replace('_', ' ', $method)),
54                'orders' => $group->count(),
55                'revenue' => (float) $group->sum('total'),
56            ])
57            ->sortByDesc('revenue')
58            ->values();
59    }
60
61    public function summary(Collection $rows, array $filters): array
62    {
63        return [
64            'Methods Used' => number_format($rows->count()),
65            'Total Revenue' => money($rows->sum('revenue')),
66        ];
67    }
68}