Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
CreateListingAgreementAction
100.00% covered (success)
100.00%
45 / 45
100.00% covered (success)
100.00%
2 / 2
8
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%
44 / 44
100.00% covered (success)
100.00%
1 / 1
7
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\ListingAgreementStatus;
11use ImovelZapAi\Owners\Domain\Enums\ListingAgreementType;
12use ImovelZapAi\Owners\Domain\Enums\ListingHistoryEvent;
13use ImovelZapAi\Owners\Domain\Enums\ListingStageKey;
14use ImovelZapAi\Owners\Domain\Events\ListingAgreementCreated;
15use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\ListingAgreementModel;
16use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\ListingOpportunityModel;
17use ImovelZapAi\Owners\Infrastructure\Persistence\Eloquent\OwnerModel;
18
19final class CreateListingAgreementAction
20{
21    public function __construct(
22        private readonly ListingHistoryWriter $history,
23        private readonly ChangeListingStageAction $changeStage,
24    ) {}
25
26    /**
27     * @param  array{
28     *     owner_id: string,
29     *     property_id?: string|null,
30     *     listing_opportunity_id?: string|null,
31     *     type: string,
32     *     starts_on: string,
33     *     ends_on: string,
34     *     commission_percent?: float|string|null,
35     *     auto_renew?: bool,
36     *     notes?: string|null,
37     *     activate?: bool,
38     *     responsible_user_id?: int|null,
39     * }  $data
40     */
41    public function execute(string $tenantId, User $actor, array $data): ListingAgreementModel
42    {
43        return DB::transaction(function () use ($tenantId, $actor, $data): ListingAgreementModel {
44            OwnerModel::query()->where('tenant_id', $tenantId)->whereKey($data['owner_id'])->firstOrFail();
45
46            $activate = (bool) ($data['activate'] ?? true);
47            $agreement = ListingAgreementModel::query()->create([
48                'tenant_id' => $tenantId,
49                'owner_id' => $data['owner_id'],
50                'property_id' => $data['property_id'] ?? null,
51                'listing_opportunity_id' => $data['listing_opportunity_id'] ?? null,
52                'responsible_user_id' => $data['responsible_user_id'] ?? $actor->id,
53                'created_by' => $actor->id,
54                'type' => ListingAgreementType::from($data['type']),
55                'status' => $activate ? ListingAgreementStatus::Active : ListingAgreementStatus::Draft,
56                'starts_on' => $data['starts_on'],
57                'ends_on' => $data['ends_on'],
58                'auto_renew' => (bool) ($data['auto_renew'] ?? false),
59                'commission_percent' => $data['commission_percent'] ?? null,
60                'notes' => $data['notes'] ?? null,
61                'signed_at' => $activate ? now() : null,
62            ]);
63
64            $this->history->write(
65                $tenantId,
66                ListingHistoryEvent::AgreementCreated,
67                opportunityId: $agreement->listing_opportunity_id,
68                ownerId: $agreement->owner_id,
69                agreementId: $agreement->id,
70                actorUserId: (int) $actor->id,
71                message: 'Contrato de captação criado.',
72            );
73
74            ListingAgreementCreated::dispatch($tenantId, $agreement->id);
75
76            if ($activate && $agreement->listing_opportunity_id !== null) {
77                $opportunity = ListingOpportunityModel::query()->find($agreement->listing_opportunity_id);
78                if ($opportunity !== null && ! $opportunity->isClosed()) {
79                    $this->changeStage->execute($opportunity, $actor, ListingStageKey::AgreementSigned->value);
80                    $this->history->write(
81                        $tenantId,
82                        ListingHistoryEvent::AgreementActivated,
83                        opportunityId: $opportunity->id,
84                        ownerId: $agreement->owner_id,
85                        agreementId: $agreement->id,
86                        actorUserId: (int) $actor->id,
87                        message: 'Contrato ativado.',
88                    );
89                }
90            }
91
92            return $agreement->fresh(['owner', 'property']);
93        });
94    }
95}