Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
CreateVisitRequestAction
100.00% covered (success)
100.00%
41 / 41
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%
40 / 40
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Visits\Application\Actions;
6
7use App\Models\User;
8use Illuminate\Support\Facades\DB;
9use ImovelZapAi\Visits\Application\Services\VisitLogWriter;
10use ImovelZapAi\Visits\Application\Services\VisitSnapshotter;
11use ImovelZapAi\Visits\Domain\Enums\VisitLogEvent;
12use ImovelZapAi\Visits\Domain\Enums\VisitParticipantRole;
13use ImovelZapAi\Visits\Domain\Enums\VisitStatus;
14use ImovelZapAi\Visits\Domain\Events\VisitCreated;
15use ImovelZapAi\Visits\Infrastructure\Persistence\Eloquent\VisitModel;
16use ImovelZapAi\Visits\Infrastructure\Persistence\Eloquent\VisitParticipantModel;
17
18final class CreateVisitRequestAction
19{
20    public function __construct(
21        private readonly VisitLogWriter $logWriter,
22        private readonly VisitSnapshotter $snapshotter,
23    ) {}
24
25    /**
26     * @param  array{
27     *     contact_id: string,
28     *     property_id?: string|null,
29     *     conversation_id?: string|null,
30     *     property_interest_id?: string|null,
31     *     owner_id?: string|null,
32     *     listing_opportunity_id?: string|null,
33     *     purpose?: string|null,
34     *     responsible_user_id?: int|null,
35     *     location_notes?: string|null,
36     * }  $data
37     */
38    public function execute(string $tenantId, User $actor, array $data): VisitModel
39    {
40        return DB::transaction(function () use ($tenantId, $actor, $data): VisitModel {
41            $visit = VisitModel::query()->create([
42                'tenant_id' => $tenantId,
43                'contact_id' => $data['contact_id'],
44                'property_id' => $data['property_id'] ?? null,
45                'conversation_id' => $data['conversation_id'] ?? null,
46                'property_interest_id' => $data['property_interest_id'] ?? null,
47                'owner_id' => $data['owner_id'] ?? null,
48                'listing_opportunity_id' => $data['listing_opportunity_id'] ?? null,
49                'purpose' => $data['purpose'] ?? \ImovelZapAi\Visits\Domain\Enums\VisitPurpose::BuyerVisit->value,
50                'responsible_user_id' => $data['responsible_user_id'] ?? $actor->id,
51                'created_by' => $actor->id,
52                'status' => VisitStatus::Requested,
53                'location_notes' => $data['location_notes'] ?? null,
54                'timezone' => 'America/Sao_Paulo',
55            ]);
56
57            VisitParticipantModel::query()->create([
58                'tenant_id' => $tenantId,
59                'visit_id' => $visit->id,
60                'contact_id' => $data['contact_id'],
61                'role' => VisitParticipantRole::Client,
62            ]);
63
64            if ($visit->responsible_user_id !== null) {
65                VisitParticipantModel::query()->create([
66                    'tenant_id' => $tenantId,
67                    'visit_id' => $visit->id,
68                    'user_id' => $visit->responsible_user_id,
69                    'role' => VisitParticipantRole::Responsible,
70                ]);
71            }
72
73            $this->logWriter->write(
74                $tenantId,
75                $visit->id,
76                VisitLogEvent::Created,
77                actorUserId: (int) $actor->id,
78                after: $this->snapshotter->snapshot($visit),
79                message: 'Solicitação de visita criada.',
80            );
81
82            VisitCreated::dispatch($tenantId, $visit->id);
83
84            return $visit->fresh(['participants', 'contact', 'property']);
85        });
86    }
87}