Passed
Push — master ( a66ce3...649994 )
by Luiz Kim
02:42
created

SignatureService::addDocumentSignersFromContract()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 33
rs 9.0111
cc 6
nc 8
nop 2
1
<?php
2
3
namespace Controleonline\Service;
4
5
use ControleOnline\Entity\People;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\People was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use ControleOnline\Entity\Contract;
7
use App\Library\Provider\Signature\Document;
0 ignored issues
show
Bug introduced by
The type App\Library\Provider\Signature\Document was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use App\Library\Provider\Signature\Signer;
0 ignored issues
show
Bug introduced by
The type App\Library\Provider\Signature\Signer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Doctrine\ORM\EntityManagerInterface;
0 ignored issues
show
Bug introduced by
The type Doctrine\ORM\EntityManagerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use App\Library\Provider\Signature\SignatureFactory;
0 ignored issues
show
Bug introduced by
The type App\Library\Provider\Signature\SignatureFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use ControleOnline\Entity\Config;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use ControleOnline\Entity\Status;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\Status was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use ControleOnline\Service\ContractService;
14
use ControleOnline\Service\PeopleRoleService;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Service\PeopleRoleService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Exception;
16
17
class SignatureService
18
{
19
    protected $request;
20
    protected $signatureProvider;
21
    public function __construct(
22
        private EntityManagerInterface $manager,
23
        private PeopleRoleService $peopleRoleService,
24
        private ContractService $contractService,
25
    ) {}
26
27
28
    public function sign(Contract $data)
29
    {
30
31
        $this->signatureProvider = $this->getFactory($data);
32
33
        if ($this->signatureProvider !== null) {
34
35
36
            $document = ($this->signatureProvider->createDocument())
37
                ->setFileName(
38
                    sprintf('Contrato-%s', $this->getContractContractorSignerName($data))
39
                )
40
                ->setContent(
41
                    $this->contractService->getContractPDFContent($data)
42
                )
43
                ->setDeadlineAt(
44
                    (new \DateTime('now'))
45
                        ->add(new \DateInterval('P7D'))
46
                        ->format('c')
47
                );
48
            /*
49
            $this->addDocumentSignersFromContract($document, $data);
50
            $this->signatureProvider->saveDocument($document);
51
            */
52
53
            $data->setStatus(
54
                $this->manager->getRepository(Status::class)->findOneBy(
55
                    ['status' => 'Waiting Signature']
56
                )
57
            );
58
            $data->setDocKey($document->getKey());
59
60
            $this->manager->persist($data);
61
            $this->manager->flush();
62
        }
63
        return $data;
64
    }
65
66
67
    private function getProviderConfig(string $providerName): ?array
68
    {
69
70
        $myCompany = $this->peopleRoleService->getMainCompany();
71
        if ($myCompany instanceof People) {
72
73
            return $this->manager->getRepository(Config::class)
74
                ->getKeyValuesByPeople(
75
                    $myCompany,
76
                    strtolower($providerName)
77
                );
78
        }
79
80
        throw new \Exception('Company not found');
81
    }
82
83
    private function getDefaultProviderFromConfig(Contract $data): ?string
84
    {
85
        $myCompany = $data->getBeneficiary();
86
87
88
        if ($myCompany instanceof People) {
89
            $configs = $this->manager->getRepository(Config::class)
90
                ->getKeyValuesByPeople(
91
                    $myCompany,
92
                    'provider'
93
                );
94
95
            if ($configs === null) {
96
                return null;
97
            }
98
99
            return isset($configs['provider-signature']) ?
100
                $configs['provider-signature'] : null;
101
        }
102
103
        throw new \Exception('Company not found');
104
    }
105
106
    private function getFactory(Contract $data): ?SignatureFactory
107
    {
108
        $providerName =
109
            $this->getDefaultProviderFromConfig($data);
110
111
        if ($providerName === null) {
112
            return null;
113
        }
114
115
        $provider = sprintf(
116
            '\\App\\Library\\Provider\\Signature\\%s\\Factory',
117
            ucfirst(strtolower($providerName))
118
        );
119
120
        if (!class_exists($provider)) {
121
            throw new \Exception('Signature provider factory not found');
122
        }
123
124
        return new $provider(
125
            $this->getProviderConfig($providerName)
126
        );
127
    }
128
129
    protected function addDocumentSignersFromContract(Document $document, Contract $contract)
130
    {
131
        if ($contract->getPeoples()->isEmpty()) {
132
            throw new Exception('Este contrato não tem assinantes');
133
        }
134
135
        $contractProviders = $contract->getPeoples()
136
            ->filter(function ($contractPeople) {
137
                return $contractPeople->getPeopleType() == 'Beneficiary';
138
            });
139
        if ($contractProviders->isEmpty()) {
140
            throw new Exception('O prestador de serviços não foi definido');
141
        }
142
143
        foreach ($contractProviders as $provider) {
144
            $document->addSigner(
145
                $this->getSignerFromPeople($provider->getPeople(), 'prestador de serviços')
146
            );
147
        }
148
149
        $contractParticipants = $contract->getPeoples()
150
            ->filter(function ($contractPeople) {
151
                return $contractPeople->getPeopleType() != 'Beneficiary';
152
            });
153
        if ($contractParticipants->isEmpty()) {
154
            throw new Exception(
155
                'Devem existir pelo menos 1 assinante no contrato'
156
            );
157
        }
158
159
        foreach ($contractParticipants as $participant) {
160
            $document->addSigner(
161
                $this->getSignerFromPeople($participant->getPeople(), 'assinante')
162
            );
163
        }
164
    }
165
166
    protected function getContractContractorSignerName(Contract $contract): string
167
    {
168
        $contractPayers = $contract->getPeoples()
169
            ->filter(function ($contractPeople) {
170
                return $contractPeople->getPeopleType() == 'Contractor';
171
            });
172
        if ($contractPayers->isEmpty()) {
173
            throw new Exception(
174
                'Devem existir pelo menos 1 assinante como contratante'
175
            );
176
        }
177
178
        return $contractPayers->first()->getPeople()->getFullName();
179
    }
180
181
182
    protected function getSignerFromPeople(People $people, string $role): Signer
183
    {
184
        $signer = $this->signatureProvider->createSigner();
185
186
        $signer->setKey($people->getId());
187
        $signer->setName($people->getFullName());
188
189
        if (($email = $people->getOneEmail()) === null) {
190
            throw new Exception(
191
                sprintf('O %s "%s" não possui um email', $role, $people->getFullName())
192
            );
193
        }
194
195
        $signer->setEmail($email->getEmail());
196
197
        if ($people->getPeopleType() == 'F') {
198
            $signer->setHasCPF(true);
199
200
            if (($document = $people->getOneDocument()) === null) {
201
                throw new Exception(
202
                    sprintf('O %s "%s" não possui um CPF/CNPJ', $role, $people->getFullName())
203
                );
204
            }
205
206
            $signer->setCPF($document->getDocument());
207
            if (($birthday = $people->getBirthdayAsString()) === null) {
208
                throw new Exception(
209
                    sprintf(
210
                        'O %s "%s" não tem data de nascimento definida',
211
                        $role,
212
                        $people->getFullName()
213
                    )
214
                );
215
            }
216
217
            $signer->setBirthday($birthday);
218
        }
219
220
        return $signer;
221
    }
222
}
223