VatNumberValidator   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 46
dl 0
loc 104
rs 10
c 2
b 0
f 0
wmc 28

6 Methods

Rating   Name   Duplication   Size   Complexity  
A validateRegistration() 0 19 4
A hasVatNumberForCompany() 0 13 5
C validate() 0 40 13
A hasVatNumberForCountry() 0 12 4
A addViolation() 0 3 1
A __construct() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewebe\SyliusVATPlugin\Validator\Constraints;
6
7
use Gewebe\SyliusVATPlugin\Config\VatNumberValidatorConfig;
0 ignored issues
show
Bug introduced by
The type Gewebe\SyliusVATPlugin\C...atNumberValidatorConfig 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 Gewebe\SyliusVATPlugin\Entity\VatNumberAddressInterface;
9
use Gewebe\SyliusVATPlugin\Vat\Number\ClientException;
10
use Gewebe\SyliusVATPlugin\Vat\Number\VatNumberValidatorInterface;
11
use Gewebe\SyliusVATPlugin\Vat\Number\VatNumberValidatorProviderInterface;
12
use Symfony\Component\Validator\Constraint;
13
use Symfony\Component\Validator\ConstraintValidator;
14
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
15
use Symfony\Component\Validator\Exception\UnexpectedValueException;
16
17
class VatNumberValidator extends ConstraintValidator
18
{
19
    public function __construct(
20
        private readonly VatNumberValidatorProviderInterface $validatorProvider,
21
        private readonly VatNumberValidatorConfig $validatorConfig,
22
    ) {
23
    }
24
25
    public function validate(mixed $value, Constraint $constraint): void
26
    {
27
        if (!$constraint instanceof VatNumber) {
28
            throw new UnexpectedTypeException($constraint, VatNumber::class);
29
        }
30
31
        if (!$value instanceof VatNumberAddressInterface) {
32
            throw new UnexpectedValueException($value, VatNumberAddressInterface::class);
33
        }
34
35
        if ($this->hasVatNumberForCompany($value, $constraint) === false ||
36
            $this->hasVatNumberForCountry($value, $constraint) === false ||
37
            $this->validatorConfig->validateFormat === false ||
38
            !$value->getVatNumber() ||
39
            !$value->getCountryCode()
40
        ) {
41
            return;
42
        }
43
44
        $vatNumberValidator = $this->validatorProvider->getValidator($value->getCountryCode());
45
        if (null === $vatNumberValidator) {
46
            return;
47
        }
48
49
        if ($vatNumberValidator->validateFormat($value->getVatNumber()) === false) {
50
            $this->addViolation($constraint->messageInvalidFormat, $constraint->vatNumberPath);
51
52
            return;
53
        }
54
55
        if ($this->validatorConfig->validateCountry &&
56
            $vatNumberValidator->validateCountry($value->getVatNumber(), $value->getCountryCode()) === false
57
        ) {
58
            $this->addViolation($constraint->messageInvalidCountry, $constraint->vatNumberPath);
59
60
            return;
61
        }
62
63
        if ($this->validatorConfig->validateRegistration) {
64
            $this->validateRegistration($value, $vatNumberValidator, $constraint);
65
        }
66
    }
67
68
    private function addViolation(string $message, string $path): void
69
    {
70
        $this->context->buildViolation($message)->atPath($path)->addViolation();
71
    }
72
73
    private function hasVatNumberForCompany(VatNumberAddressInterface $address, VatNumber $constraint): bool
74
    {
75
        if ($this->validatorConfig->isRequiredForCompany &&
76
            $address->getCompany() !== null &&
77
            $address->getCompany() !== '' &&
78
            $address->hasVatNumber() === false
79
        ) {
80
            $this->addViolation($constraint->messageRequiredForCompany, $constraint->vatNumberPath);
81
82
            return false;
83
        }
84
85
        return true;
86
    }
87
88
    private function hasVatNumberForCountry(VatNumberAddressInterface $address, VatNumber $constraint): bool
89
    {
90
        if (count($this->validatorConfig->requiredForCountries) > 0 &&
91
            in_array($address->getCountryCode(), $this->validatorConfig->requiredForCountries, true) &&
92
            $address->hasVatNumber() === false
93
        ) {
94
            $this->addViolation($constraint->messageRequired, $constraint->vatNumberPath);
95
96
            return false;
97
        }
98
99
        return true;
100
    }
101
102
    private function validateRegistration(
103
        VatNumberAddressInterface $address,
104
        VatNumberValidatorInterface $validator,
105
        VatNumber $constraint,
106
    ): void {
107
        try {
108
            $validVatNumber = $validator->validate($address->getVatNumber() ?? '');
109
        } catch (ClientException $e) {
110
            if ($this->validatorConfig->validateOnServiceUnavailable === true) {
111
                $this->addViolation($constraint->messageServiceUnavailable, $constraint->vatNumberPath);
112
            }
113
114
            return;
115
        }
116
117
        $address->setVatValid($validVatNumber);
118
119
        if (false === $validVatNumber) {
120
            $this->addViolation($constraint->messageInvalidRegistration, $constraint->vatNumberPath);
121
        }
122
    }
123
}
124