Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
49 / 49
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
CreateOwnerAction
100.00% covered (success)
100.00%
49 / 49
100.00% covered (success)
100.00%
2 / 2
6
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%
48 / 48
100.00% covered (success)
100.00%
1 / 1
5
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\Enums\OwnerContactChannel;
12use ImovelZapAi\Owners\Domain\Enums\OwnerType;
13use ImovelZapAi\Owners\Domain\Events\OwnerCreated;
14use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\OwnerAddressModel;
15use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\OwnerContactModel;
16use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\OwnerDocumentModel;
17use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\OwnerModel;
18
19final class CreateOwnerAction
20{
21    public function __construct(
22        private readonly ListingHistoryWriter $history,
23    ) {}
24
25    /**
26     * @param  array{
27     *     name: string,
28     *     type?: string|null,
29     *     document?: string|null,
30     *     trade_name?: string|null,
31     *     notes?: string|null,
32     *     preferred_contact_channel?: string|null,
33     *     preferences?: array<string, mixed>|null,
34     *     responsible_user_id?: int|null,
35     *     contacts?: list<array{channel: string, value: string, label?: string|null, is_primary?: bool}>,
36     *     addresses?: list<array<string, mixed>>,
37     *     documents?: list<array{type: string, name: string, path?: string|null, notes?: string|null}>,
38     * }  $data
39     */
40    public function execute(string $tenantId, User $actor, array $data): OwnerModel
41    {
42        return DB::transaction(function () use ($tenantId, $actor, $data): OwnerModel {
43            $owner = OwnerModel::query()->create([
44                'tenant_id' => $tenantId,
45                'type' => OwnerType::tryFrom((string) ($data['type'] ?? 'person')) ?? OwnerType::Person,
46                'name' => $data['name'],
47                'document' => $data['document'] ?? null,
48                'trade_name' => $data['trade_name'] ?? null,
49                'notes' => $data['notes'] ?? null,
50                'preferred_contact_channel' => isset($data['preferred_contact_channel'])
51                    ? OwnerContactChannel::tryFrom((string) $data['preferred_contact_channel'])
52                    : null,
53                'preferences' => $data['preferences'] ?? null,
54                'responsible_user_id' => $data['responsible_user_id'] ?? $actor->id,
55                'created_by' => $actor->id,
56                'last_contacted_at' => now(),
57            ]);
58
59            foreach ($data['contacts'] ?? [] as $contact) {
60                OwnerContactModel::query()->create([
61                    'tenant_id' => $tenantId,
62                    'owner_id' => $owner->id,
63                    'channel' => OwnerContactChannel::from($contact['channel']),
64                    'value' => $contact['value'],
65                    'label' => $contact['label'] ?? null,
66                    'is_primary' => (bool) ($contact['is_primary'] ?? false),
67                ]);
68            }
69
70            foreach ($data['addresses'] ?? [] as $address) {
71                OwnerAddressModel::query()->create(array_merge($address, [
72                    'tenant_id' => $tenantId,
73                    'owner_id' => $owner->id,
74                ]));
75            }
76
77            foreach ($data['documents'] ?? [] as $document) {
78                OwnerDocumentModel::query()->create([
79                    'tenant_id' => $tenantId,
80                    'owner_id' => $owner->id,
81                    'type' => $document['type'],
82                    'name' => $document['name'],
83                    'path' => $document['path'] ?? null,
84                    'notes' => $document['notes'] ?? null,
85                ]);
86            }
87
88            $this->history->write(
89                $tenantId,
90                ListingHistoryEvent::OwnerCreated,
91                ownerId: $owner->id,
92                actorUserId: (int) $actor->id,
93                message: 'Proprietário cadastrado.',
94            );
95
96            OwnerCreated::dispatch($tenantId, $owner->id);
97
98            return $owner->fresh(['contacts', 'addresses', 'documents']);
99        });
100    }
101}