Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
12.50% covered (danger)
12.50%
4 / 32
50.00% covered (danger)
50.00%
4 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SupplierDueReport
12.50% covered (danger)
12.50%
4 / 32
50.00% covered (danger)
50.00%
4 / 8
50.88
0.00% covered (danger)
0.00%
0 / 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
 filters
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 columns
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 rows
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 summary
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Reports\Purchase;
4
5use App\Models\admin\Supplier;
6use App\Reports\Report;
7use Illuminate\Support\Collection;
8
9/** How much is owed to each supplier, all-time — no date filter, this is a snapshot. */
10class SupplierDueReport extends Report
11{
12    public function key(): string
13    {
14        return 'supplier-due';
15    }
16
17    public function label(): string
18    {
19        return 'Supplier Dues (Payable)';
20    }
21
22    public function group(): string
23    {
24        return 'Purchase';
25    }
26
27    public function description(): ?string
28    {
29        return 'Outstanding payable to each supplier across every purchase.';
30    }
31
32    public function filters(): array
33    {
34        return [];
35    }
36
37    public function columns(): array
38    {
39        return [
40            ['key' => 'name', 'label' => 'Supplier'],
41            ['key' => 'purchases', 'label' => 'Purchases', 'align' => 'right'],
42            ['key' => 'total', 'label' => 'Total', 'align' => 'right', 'render' => fn ($r) => money($r->total)],
43            ['key' => 'paid', 'label' => 'Paid', 'align' => 'right', 'render' => fn ($r) => money($r->paid)],
44            ['key' => 'due', 'label' => 'Due', 'align' => 'right', 'render' => fn ($r) => money($r->due)],
45        ];
46    }
47
48    public function rows(array $filters): Collection
49    {
50        return Supplier::query()
51            ->with('purchases.purchase_payment')
52            ->get()
53            ->map(function (Supplier $s) {
54                $payments = $s->purchases->map(fn ($p) => $p->purchase_payment)->filter();
55
56                return (object) [
57                    'name' => $s->name,
58                    'purchases' => $s->purchases->count(),
59                    'total' => (float) $payments->sum('total'),
60                    'paid' => (float) $payments->sum('paid'),
61                    'due' => (float) $payments->sum('due'),
62                ];
63            })
64            ->filter(fn ($r) => $r->purchases > 0)
65            ->sortByDesc('due')
66            ->values();
67    }
68
69    public function summary(Collection $rows, array $filters): array
70    {
71        return [
72            'Suppliers with purchases' => number_format($rows->count()),
73            'Total Payable' => money($rows->sum('due')),
74        ];
75    }
76}