Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ListExpensesHandler
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handle
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Expense\Application\Query;
6
7use App\Expense\Domain\Expense;
8use App\Expense\Domain\ExpenseRepository;
9use App\Expense\Domain\ValueObject\TripId as ExpenseTripId;
10use App\Shared\Domain\ValueObject\Currency;
11use App\Trip\Application\TripAccess;
12use App\Trip\Domain\ValueObject\TripId;
13
14final readonly class ListExpensesHandler
15{
16    public function __construct(
17        private ExpenseRepository $expenses,
18        private TripAccess $access,
19        private ExpenseViewFactory $views,
20    ) {
21    }
22
23    /**
24     * @return list<ExpenseView>
25     */
26    public function handle(ListExpensesQuery $query): array
27    {
28        // Any role may read: a missing/foreign trip surfaces as TripNotFound (404).
29        $this->access->getReadable(new TripId($query->tripId), $query->userId);
30
31        $preferred = new Currency($query->preferredCurrency);
32
33        return array_map(
34            fn (Expense $expense) => $this->views->create($expense, $preferred),
35            $this->expenses->ofTrip(new ExpenseTripId($query->tripId)),
36        );
37    }
38}