Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
UpdateExpenseHandler
100.00% covered (success)
100.00%
16 / 16
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%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Expense\Application\Command;
6
7use App\Expense\Application\OwnedExpenseFinder;
8use App\Expense\Application\Query\ExpenseView;
9use App\Expense\Domain\Category;
10use App\Expense\Domain\ExpenseRepository;
11use App\Expense\Domain\ValueObject\ExpenseId;
12use App\Shared\Domain\ValueObject\IsoDate;
13use App\Shared\Domain\ValueObject\Money;
14use App\Trip\Domain\ValueObject\TripId;
15use InvalidArgumentException;
16
17final readonly class UpdateExpenseHandler
18{
19    public function __construct(
20        private OwnedExpenseFinder $finder,
21        private ExpenseRepository $expenses,
22    ) {
23    }
24
25    public function handle(UpdateExpenseCommand $command): ExpenseView
26    {
27        $expense = $this->finder->getForWrite(
28            new TripId($command->tripId),
29            $command->userId,
30            new ExpenseId($command->expenseId),
31        );
32
33        $category = Category::tryFrom($command->category)
34            ?? throw new InvalidArgumentException(sprintf('Unknown expense category <%s>.', $command->category));
35
36        // Currency is fixed (the trip currency); the amount stays in it.
37        $expense->update(
38            new Money($command->amount, $expense->money()->currency()),
39            $category,
40            $command->description,
41            IsoDate::parse($command->spentAt),
42        );
43
44        $this->expenses->save($expense);
45
46        return ExpenseView::fromExpense($expense);
47    }
48}