Passed
Push — master ( b4cdc7...6d8b5e )
by Luiz Kim
06:08 queued 03:50
created

PeopleService::discoveryPeople()   B

Complexity

Conditions 11
Paths 128

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 20
c 2
b 0
f 0
nc 128
nop 5
dl 0
loc 30
rs 7.0833

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace ControleOnline\Service;
4
5
use ControleOnline\Entity\Document;
6
use ControleOnline\Entity\DocumentType;
7
use ControleOnline\Entity\Email;
8
use ControleOnline\Entity\ExtraData;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\ExtraData 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 ControleOnline\Entity\ExtraFields;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\ExtraFields 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 ControleOnline\Entity\Language;
0 ignored issues
show
Bug introduced by
The type ControleOnline\Entity\Language 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\People;
12
use ControleOnline\Entity\PeopleLink;
13
use ControleOnline\Entity\Phone;
14
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...
15
use Symfony\Component\HttpFoundation\RequestStack;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\RequestStack 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...
16
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Securi...e\TokenStorageInterface 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...
17
as Security;
18
use Doctrine\ORM\QueryBuilder;
0 ignored issues
show
Bug introduced by
The type Doctrine\ORM\QueryBuilder 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...
19
use Exception;
20
21
class PeopleService
22
{
23
  private $request;
24
25
  public function __construct(
26
    private EntityManagerInterface $manager,
27
    private Security               $security,
28
    private RequestStack $requestStack,
29
  ) {
30
    $this->request  = $requestStack->getCurrentRequest();
31
  }
32
33
  public function prePersist(People $people)
34
  {
35
    $language = $this->manager->getRepository(Language::class)->findOneBy(['language' => 'pt-br']);
36
    $people->setLanguage($language);
37
    return $people;
38
  }
39
40
  public function addClient() {}
41
42
43
  public function discoveryClient(People $provider, People $client)
44
  {
45
    return $this->discoveryLink($provider, $client, 'client');
46
  }
47
48
  public function discoveryLink(People $company, People $people, $linkType): PeopleLink
49
  {
50
    $peopleLink =   $this->manager->getRepository(PeopleLink::class)->findOneBy([
51
      'company' => $company,
52
      'people' => $people,
53
      'link_type' => $linkType
54
    ]);
55
56
    if (!$peopleLink)
57
      $peopleLink = $this->addLink($company, $people, $linkType);
58
59
    return $peopleLink;
60
  }
61
62
  public function discoveryPeople(?string $document = null, ?string  $email = null, ?array $phone = [], ?string $name = null, ?string $peopleType = null): People
63
  {
64
65
    if (!empty($document))
66
      $people = $this->getDocument($document)?->getPeople();
67
68
    if (!$people && !empty($email))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $people does not seem to be defined for all execution paths leading up to this point.
Loading history...
69
      $people = $this->getEmail($email)?->getPeople();
70
71
    if (!$people && !empty($phone))
72
      $people = $this->getPhone($phone['ddd'], $phone['phone'])?->getPeople();
73
74
    if (!$people) {
75
      $people = new People();
76
      $people->setName($name ?? 'Name not given');
77
      $people->setLanguage($this->manager->getRepository(Language::class)->findOneBy(['language' => 'pt-br']));
78
      $people->setPeopleType($peopleType ?: $this->getPeopleTypeByDocumentLen($document));
79
      $this->manager->persist($people);
80
      $this->manager->flush();
81
    }
82
83
    if ($document)
84
      $this->addDocument($people, $document);
85
    if ($email)
86
      $this->addEmail($people, $email);
87
    if ($phone)
88
      $this->addPhone($people, $phone);
89
90
91
    return $people;
92
  }
93
94
  public function addPhone(People $people, array $phone_number): Phone
95
  {
96
    $phone = $this->getPhone($phone_number['ddd'], $phone_number['phone']);
97
    if ($phone && $phone->getPeople()) {
98
      if ($phone->getPeople()->getId() != $people->getId())
99
        throw new Exception("Phone is in use by people " . $people->getId(), 1);
100
    } else {
101
      $phone = new Phone();
102
      $phone->setDdd((int) $phone_number['ddd']);
103
      $phone->setPhone((int) $phone_number['phone']);
104
      $phone->setPeople($people);
105
      $this->manager->persist($phone);
106
      $this->manager->flush();
107
    }
108
109
    return  $phone;
110
  }
111
  public function addDocument(People $people, string|int $document_number, ?string $document_type = null): Document
112
  {
113
    $document = $this->getDocument($document_number, $document_type);
114
    if ($document) {
115
      if ($document->getPeople()->getId() != $people->getId())
116
        throw new Exception("Document is in use by people " . $people->getId(), 1);
117
    } else {
118
      $document_type = $document_type ? $this->discoveryDocumentType($document_type) : $this->discoveryDocumentType($this->getDocumentTypeByDocumentLen($document_number));
119
      $document = new Document();
120
      $document->setDocument((int)$document_number);
121
      $document->setDocumentType($document_type);
122
      $document->setPeople($people);
123
      $this->manager->persist($document);
124
      $this->manager->flush();
125
    }
126
127
    return  $document;
128
  }
129
130
  public function addEmail(People $people, string $email_str): Email
131
  {
132
    $email = $this->getEmail($email_str);
133
    if ($email && $email->getPeople()) {
134
      if ($email->getPeople()->getId() != $people->getId())
135
        throw new Exception("Email is in use by people " . $people->getId(), 1);
136
    } else {
137
      $email = new Email();
138
      $email->setEmail($email_str);
139
      $email->setPeople($people);
140
      $this->manager->persist($email);
141
      $this->manager->flush();
142
    }
143
144
    return  $email;
145
  }
146
147
  public function getEmail(string $email): ?Email
148
  {
149
    return $this->manager->getRepository(Email::class)->findOneBy(['email' => $email]);
150
  }
151
152
  public function getPhone(string $ddd, string $phone): ?Phone
153
  {
154
    return $this->manager->getRepository(Phone::class)->findOneBy(['ddd' => $ddd, 'ddd' => $phone]);
155
  }
156
157
158
  public function discoveryDocumentType(string $document_type): DocumentType
159
  {
160
    $documentType =  $this->manager->getRepository(DocumentType::class)->findOneBy(['documentType' => $document_type]);
161
162
    if (!$documentType) {
163
      $documentType = new DocumentType();
164
      $documentType->setDocumentType($document_type);
165
      $this->manager->persist($documentType);
166
      $this->manager->flush();
167
    }
168
169
    return $documentType;
170
  }
171
172
  public function getDocument(string $document_number, ?string $document_type = null): ?Document
173
  {
174
    if (!$document_type)
175
      $document_type = $this->getDocumentTypeByDocumentLen($document_number);
176
    return $this->manager->getRepository(Document::class)->findOneBy([
177
      'document' => $document_number,
178
      'documentType' =>
179
      $this->discoveryDocumentType($document_type)
180
    ]);
181
  }
182
183
  public function getPeopleTypeByDocumentLen(?string $document_number = null)
184
  {
185
    return strlen($document_number) > 11 ? 'J' : 'F';
0 ignored issues
show
Bug introduced by
It seems like $document_number can also be of type null; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

185
    return strlen(/** @scrutinizer ignore-type */ $document_number) > 11 ? 'J' : 'F';
Loading history...
186
  }
187
188
  public function getDocumentTypeByDocumentLen(?string $document_number = null)
189
  {
190
    return strlen($document_number) > 11 ? 'CNPJ' : 'CPF';
0 ignored issues
show
Bug introduced by
It seems like $document_number can also be of type null; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

190
    return strlen(/** @scrutinizer ignore-type */ $document_number) > 11 ? 'CNPJ' : 'CPF';
Loading history...
191
  }
192
193
  public function postPersist(People $people)
194
  {
195
    $request = $this->requestStack->getCurrentRequest();
196
    if (!$request) return;
197
    $payload   = json_decode($request->getContent());
198
    if (isset($payload->link_type)) {
199
      $company = $this->manager->getRepository(People::class)->find(preg_replace('/\D/', '', $payload->company));
200
      if ($company)
201
        $this->discoveryLink($company, $people, $payload->link_type);
202
      else {
203
        $link = $this->manager->getRepository(People::class)->find(preg_replace('/\D/', '', $payload->link));
204
        if ($payload->link_type == 'employee' && $link) {
205
          $this->discoveryLink($people, $link, $payload->link_type);
206
          if ($payload->people_document)
207
            $this->addDocument($people, $payload->people_document);
208
        }
209
      }
210
    }
211
  }
212
213
  public function addLink(People $company, People $people, $link_type): PeopleLink
214
  {
215
216
    $peopleLink = $this->manager->getRepository(PeopleLink::class)->findOneBy([
217
      'company' => $company,
218
      'people' => $people,
219
      'link_type' => $link_type
220
    ]);
221
222
    if (!$peopleLink)
223
      $peopleLink = new PeopleLink();
224
225
    $peopleLink->setCompany($company);
226
    $peopleLink->setPeople($people);
227
    $peopleLink->setLinkType($link_type);
228
229
    $this->manager->persist($peopleLink);
230
    $this->manager->flush();
231
    return  $peopleLink;
232
  }
233
234
  public function securityFilter(QueryBuilder $queryBuilder, $resourceClass = null, $applyTo = null, $rootAlias = null): void
235
  {
236
    $this->checkLink($queryBuilder, $resourceClass, $applyTo, $rootAlias);
237
  }
238
239
  public function checkLink(QueryBuilder $queryBuilder, $resourceClass = null, $applyTo = null, $rootAlias = null): void
0 ignored issues
show
Unused Code introduced by
The parameter $applyTo is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

239
  public function checkLink(QueryBuilder $queryBuilder, $resourceClass = null, /** @scrutinizer ignore-unused */ $applyTo = null, $rootAlias = null): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $resourceClass is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

239
  public function checkLink(QueryBuilder $queryBuilder, /** @scrutinizer ignore-unused */ $resourceClass = null, $applyTo = null, $rootAlias = null): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
240
  {
241
242
    $link   = $this->request->query->get('link',   null);
243
    $company = $this->request->query->get('company', null);
244
    $link_type = $this->request->query->get('link_type', null);
245
246
    if ($link_type) {
247
      $queryBuilder->join(sprintf('%s.' . ($link ? 'company' : 'link'), $rootAlias), 'PeopleLink');
248
      $queryBuilder->andWhere('PeopleLink.link_type IN(:link_type)');
249
      $queryBuilder->setParameter('link_type', $link_type);
250
    }
251
252
    if ($company || $link) {
253
      $queryBuilder->andWhere('PeopleLink.' . ($link ? 'people' : 'company') . ' IN(:people)');
254
      $queryBuilder->setParameter('people', preg_replace("/[^0-9]/", "", ($link ?: $company)));
255
    }
256
  }
257
  public function checkCompany($type, QueryBuilder $queryBuilder, $resourceClass = null, $applyTo = null, $rootAlias = null): void
0 ignored issues
show
Unused Code introduced by
The parameter $resourceClass is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

257
  public function checkCompany($type, QueryBuilder $queryBuilder, /** @scrutinizer ignore-unused */ $resourceClass = null, $applyTo = null, $rootAlias = null): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $applyTo is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

257
  public function checkCompany($type, QueryBuilder $queryBuilder, $resourceClass = null, /** @scrutinizer ignore-unused */ $applyTo = null, $rootAlias = null): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
258
  {
259
    $companies   = $this->getMyCompanies();
260
    $queryBuilder->andWhere(sprintf('%s.' . $type . ' IN(:companies)', $rootAlias, $rootAlias));
261
    $queryBuilder->setParameter('companies', $companies);
262
263
    if ($payer = $this->request->query->get('company', null)) {
264
      $queryBuilder->andWhere(sprintf('%s.' . $type . ' IN(:people)', $rootAlias));
265
      $queryBuilder->setParameter('people', preg_replace("/[^0-9]/", "", $payer));
266
    }
267
  }
268
269
  public function getMyCompanies(): array
270
  {
271
    /**
272
     * @var \ControleOnline\Entity\User $currentUser
273
     */
274
    $token = $this->security->getToken();
275
    if (!$token) return [];
276
    $currentUser  =  $token->getUser();
277
    $companies    = [];
278
    if (!$currentUser) return [];
279
280
    if (!$currentUser->getPeople()->getLink()->isEmpty()) {
281
      foreach ($currentUser->getPeople()->getLink() as $company) {
282
        $companies[] = $company->getCompany();
283
      }
284
    }
285
    return $companies;
286
  }
287
}
288