Passed
Pull Request — main (#2)
by Michael
03:17
created

TaxNumber::validate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of michael-rubel/laravel-value-objects. (https://github.com/michael-rubel/laravel-value-objects)
7
 *
8
 * @link https://github.com/michael-rubel/laravel-value-objects for the canonical source repository
9
 * @copyright Copyright (c) 2022 Michael Rubél. (https://github.com/michael-rubel/)
10
 * @license https://raw.githubusercontent.com/michael-rubel/laravel-value-objects/main/LICENSE.md MIT
11
 */
12
13
namespace MichaelRubel\ValueObjects\Collection\Complex;
14
15
use MichaelRubel\Formatters\Collection\TaxNumberFormatter;
16
use MichaelRubel\ValueObjects\ValueObject;
17
18
/**
19
 * "TaxNumber" object presenting VAT identification number.
20
 *
21
 * @author Michael Rubél <[email protected]>
22
 *
23
 * @template TKey of array-key
24
 * @template TValue
25
 *
26
 * @method static static make(string|null $number, string|null $prefix = null)
27
 * @method static static from(string|null $number, string|null $prefix = null)
28
 *
29
 * @extends ValueObject<TKey, TValue>
30
 */
31
class TaxNumber extends ValueObject
32
{
33
    /**
34
     * Create a new instance of the value object.
35
     *
36
     * @param  string  $number
37
     * @param  string|null  $prefix
38
     */
39 20
    public function __construct(
40
        protected string $number,
41
        protected ?string $prefix = null,
42
    ) {
43 20
        $this->validate();
44
45 20
        $this->number = $this->format();
46
47 20
        if ($this->canSplit()) {
48 19
            $this->split();
49
        }
50
    }
51
52
    /**
53
     * Get the tax number with a country prefix.
54
     *
55
     * @return string
56
     */
57 11
    public function fullTaxNumber(): string
58
    {
59 11
        return $this->prefix() . $this->taxNumber();
60
    }
61
62
    /**
63
     * Get the tax number without country prefix.
64
     *
65
     * @return string
66
     */
67 20
    public function taxNumber(): string
68
    {
69 20
        return str($this->number)
70 20
            ->upper()
71 20
            ->value();
72
    }
73
74
    /**
75
     * Get the tax number prefix.
76
     *
77
     * @return string
78
     */
79 20
    public function prefix(): string
80
    {
81 20
        return str($this->prefix)
82 20
            ->upper()
83 20
            ->value();
84
    }
85
86
    /**
87
     * Get the country prefix for a given tax number.
88
     *
89
     * @return string
90
     */
91 10
    public function country(): string
92
    {
93 10
        return $this->prefix();
94
    }
95
96
    /**
97
     * Get the object value.
98
     *
99
     * @return string
100
     */
101 5
    public function value(): string
102
    {
103 5
        return $this->fullTaxNumber();
104
    }
105
106
    /**
107
     * Get an array representation of the value object.
108
     *
109
     * @return array
110
     */
111 1
    public function toArray(): array
112
    {
113
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('fullTaxNum...ix' => $this->prefix()) returns the type array<string,string> which is incompatible with the return type mandated by Illuminate\Contracts\Support\Arrayable::toArray() of Illuminate\Contracts\Support\TValue[].

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
114 1
            'fullTaxNumber' => $this->fullTaxNumber(),
115 1
            'taxNumber'     => $this->taxNumber(),
116 1
            'prefix'        => $this->prefix(),
117
        ];
118
    }
119
120
    /**
121
     * Format the value.
122
     *
123
     * @return string
124
     */
125 20
    protected function format(): string
126
    {
127 20
        return format(TaxNumberFormatter::class, $this->taxNumber(), $this->prefix());
128
    }
129
130
    /**
131
     * Determines whether to split the value.
132
     *
133
     * @return bool
134
     */
135 20
    protected function canSplit(): bool
136
    {
137 20
        return ! is_numeric($this->number);
138
    }
139
140
    /**
141
     * Split the value.
142
     *
143
     * @return void
144
     */
145 19
    protected function split(): void
146
    {
147 19
        $this->prefix = str($this->number)
148 19
            ->substr(0, 2)
149 19
            ->upper()
150 19
            ->value();
151
152 19
        $this->number = str($this->number)
153 19
            ->substr(2)
154 19
            ->value();
155
    }
156
157
    /**
158
     * Validate the value object data.
159
     *
160
     * @return void
161
     */
162 20
    protected function validate(): void
163
    {
164 20
        if (blank($this->number)) {
165 1
            throw new \InvalidArgumentException('Tax number cannot be blank.');
166
        }
167
    }
168
}
169