Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
SalesByProductReport
100.00% covered (success)
100.00%
24 / 24
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%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 summary
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Reports\Sales;
4
5use App\Models\OrderDetails;
6use App\Reports\Report;
7use Illuminate\Support\Collection;
8use Illuminate\Support\Facades\DB;
9
10class SalesByProductReport extends Report
11{
12    public function key(): string
13    {
14        return 'sales-by-product';
15    }
16
17    public function label(): string
18    {
19        return 'Sales by Product';
20    }
21
22    public function group(): string
23    {
24        return 'Sales';
25    }
26
27    public function description(): ?string
28    {
29        return 'Units sold and revenue per product in the selected range.';
30    }
31
32    public function columns(): array
33    {
34        return [
35            ['key' => 'name', 'label' => 'Product'],
36            ['key' => 'qty', 'label' => 'Qty Sold', 'align' => 'right'],
37            ['key' => 'revenue', 'label' => 'Revenue', 'align' => 'right', 'render' => fn ($r) => money($r->revenue)],
38        ];
39    }
40
41    public function rows(array $filters): Collection
42    {
43        return OrderDetails::query()
44            ->join('stocks', 'order_details.stock_id', '=', 'stocks.id')
45            ->join('products', 'stocks.product_id', '=', 'products.id')
46            ->join('orders', 'order_details.order_id', '=', 'orders.id')
47            ->whereDate('orders.created_at', '>=', $filters['from'])
48            ->whereDate('orders.created_at', '<=', $filters['to'])
49            ->select('products.name', DB::raw('SUM(order_details.qty) as qty'), DB::raw('SUM(order_details.total) as revenue'))
50            ->groupBy('products.id', 'products.name')
51            ->orderByDesc('revenue')
52            ->get();
53    }
54
55    public function summary(Collection $rows, array $filters): array
56    {
57        return [
58            'Products Sold' => number_format($rows->count()),
59            'Units Sold' => number_format($rows->sum('qty')),
60            'Revenue' => money($rows->sum('revenue')),
61        ];
62    }
63}