Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
UpdateListingEvaluationAction
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
2 / 2
3
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
 execute
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Owners\Application\Actions;
6
7use App\Models\User;
8use Illuminate\Support\Facades\DB;
9use ImovelZapAi\Owners\Application\Services\ListingHistoryWriter;
10use ImovelZapAi\Owners\Domain\Enums\ListingHistoryEvent;
11use ImovelZapAi\Owners\Domain\Exceptions\OwnerException;
12use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\ListingOpportunityModel;
13
14final class UpdateListingEvaluationAction
15{
16    public function __construct(
17        private readonly ListingHistoryWriter $history,
18    ) {}
19
20    /**
21     * @param  array{
22     *     owner_asking_price?: float|string|null,
23     *     agency_recommended_price?: float|string|null,
24     *     listed_price?: float|string|null,
25     *     conservation_state?: string|null,
26     *     pending_documents?: string|null,
27     *     sale_potential?: string|null,
28     *     evaluation_notes?: string|null,
29     * }  $data
30     */
31    public function execute(ListingOpportunityModel $opportunity, User $actor, array $data): ListingOpportunityModel
32    {
33        if ($opportunity->isClosed()) {
34            throw OwnerException::invalidState('oportunidade encerrada.');
35        }
36
37        return DB::transaction(function () use ($opportunity, $actor, $data): ListingOpportunityModel {
38            $before = $opportunity->only([
39                'owner_asking_price', 'agency_recommended_price', 'listed_price',
40                'conservation_state', 'pending_documents', 'sale_potential', 'evaluation_notes',
41            ]);
42
43            $opportunity->forceFill(array_merge($data, ['last_activity_at' => now()]))->save();
44
45            $this->history->write(
46                $opportunity->tenant_id,
47                ListingHistoryEvent::EvaluationUpdated,
48                opportunityId: $opportunity->id,
49                ownerId: $opportunity->owner_id,
50                actorUserId: (int) $actor->id,
51                before: $before,
52                after: $opportunity->only(array_keys($before)),
53                message: 'Avaliação atualizada.',
54            );
55
56            return $opportunity->fresh();
57        });
58    }
59}