Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.22% covered (success)
97.22%
35 / 36
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
RejectSignatureAction
97.22% covered (success)
97.22%
35 / 36
50.00% covered (danger)
50.00%
1 / 2
4
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
97.14% covered (success)
97.14%
34 / 35
0.00% covered (danger)
0.00%
0 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Signatures\Application\Actions;
6
7use Illuminate\Support\Facades\DB;
8use ImovelZapAi\Signatures\Application\Services\SignatureAccessTokenService;
9use ImovelZapAi\Signatures\Application\Services\SignatureAuditWriter;
10use ImovelZapAi\Signatures\Application\Services\SignatureStatusSynchronizer;
11use ImovelZapAi\Signatures\Domain\Enums\SignatureAuditEvent;
12use ImovelZapAi\Signatures\Domain\Enums\SignatureRequestStatus;
13use ImovelZapAi\Signatures\Domain\Enums\SignerStatus;
14use ImovelZapAi\Signatures\Domain\Events\SignatureCancelled;
15use ImovelZapAi\Signatures\Domain\Events\SignatureRejected;
16use ImovelZapAi\Signatures\Domain\Exceptions\SignatureException;
17use ImovelZapAi\Signatures\Infrastructure\Persistence\Eloquent\SignatureRequestModel;
18
19final class RejectSignatureAction
20{
21    public function __construct(
22        private readonly SignatureAccessTokenService $tokens,
23        private readonly SignatureAuditWriter $audit,
24        private readonly SignatureStatusSynchronizer $sync,
25    ) {}
26
27    public function execute(
28        string $plainToken,
29        ?string $reason = null,
30        ?string $ip = null,
31    ): SignatureRequestModel {
32        return DB::transaction(function () use ($plainToken, $reason, $ip): SignatureRequestModel {
33            $resolved = $this->tokens->resolve($plainToken);
34            $signer = $resolved['signer'];
35            $request = $resolved['request'];
36
37            if (! $request->isOpen()) {
38                throw SignatureException::invalidState('solicitação encerrada.');
39            }
40
41            $signer->forceFill([
42                'status' => SignerStatus::Rejected,
43                'rejected_at' => now(),
44            ])->save();
45
46            $request->forceFill([
47                'status' => SignatureRequestStatus::Cancelled,
48                'cancelled_at' => now(),
49            ])->save();
50
51            $this->audit->write(
52                $request->tenant_id,
53                $request->id,
54                SignatureAuditEvent::Rejected,
55                actorType: 'signer',
56                signerId: $signer->id,
57                payload: ['reason' => $reason, 'ip' => $ip],
58                message: $reason ?: 'Assinatura recusada pelo signatário.',
59            );
60
61            $this->audit->write(
62                $request->tenant_id,
63                $request->id,
64                SignatureAuditEvent::Cancelled,
65                actorType: 'system',
66                message: 'Solicitação cancelada após recusa.',
67            );
68
69            SignatureRejected::dispatch($request->tenant_id, $request->id);
70            SignatureCancelled::dispatch($request->tenant_id, $request->id);
71
72            $this->sync->sync($request);
73
74            return $request->fresh(['signers', 'document']);
75        });
76    }
77}