EEAlgorithm::isValidDate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
namespace LeKoala\Tin\Algo;
4
5
use LeKoala\Tin\Util\DateUtil;
6
use LeKoala\Tin\Util\StringUtil;
7
8
/**
9
 * Estonia
10
 */
11
class EEAlgorithm extends TINAlgorithm
12
{
13
    const LENGTH = 11;
14
    const PATTERN = "[1-6]\\d{2}[0-1]\\d[0-3]\\d{5}";
15
16
    public function validate(string $tin)
17
    {
18
        if (!$this->isFollowLength($tin)) {
19
            return StatusCode::INVALID_LENGTH;
20
        }
21
        if (!$this->isFollowPattern($tin) || !$this->isValidDate($tin)) {
22
            return StatusCode::INVALID_PATTERN;
23
        }
24
        if (!$this->isFollowRules($tin)) {
25
            return StatusCode::INVALID_SYNTAX;
26
        }
27
        return StatusCode::VALID;
28
    }
29
30
    public function isFollowLength(string $tin)
31
    {
32
        return StringUtil::isFollowLength($tin, self::LENGTH);
33
    }
34
35
    public function isFollowPattern(string $tin)
36
    {
37
        return StringUtil::isFollowPattern($tin, self::PATTERN);
38
    }
39
40
    public function isFollowRules(string $tin)
41
    {
42
        return $this->isFollowRangeRule($tin) && $this->isFollowEstoniaRule($tin);
43
    }
44
45
    public function isFollowRangeRule(string $tin)
46
    {
47
        $range = intval(StringUtil::substring($tin, 7, 10));
48
        return $range > 0 && $range < 711;
49
    }
50
51
    public function isFollowEstoniaRule(string $tin)
52
    {
53
        $c1 = StringUtil::digitAt($tin, 0);
54
        $c2 = StringUtil::digitAt($tin, 1);
55
        $c3 = StringUtil::digitAt($tin, 2);
56
        $c4 = StringUtil::digitAt($tin, 3);
57
        $c5 = StringUtil::digitAt($tin, 4);
58
        $c6 = StringUtil::digitAt($tin, 5);
59
        $c7 = StringUtil::digitAt($tin, 6);
60
        $c8 = StringUtil::digitAt($tin, 7);
61
        $c9 = StringUtil::digitAt($tin, 8);
62
        $c10 = StringUtil::digitAt($tin, 9);
63
        $c11 = StringUtil::digitAt($tin, 10);
64
        $sum = $c1 + $c2 * 2 + $c3 * 3 + $c4 * 4 + $c5 * 5 + $c6 * 6 + $c7 * 7 + $c8 * 8 + $c9 * 9 + $c10;
65
        $remainderBy11 = $sum % 11;
66
        return ($remainderBy11 < 10 && $remainderBy11 == $c11) || ($remainderBy11 == 10 && $this->isFollowEstoniaRulePart2($tin));
67
    }
68
69
    public function isFollowEstoniaRulePart2(string $tin)
70
    {
71
        $c1 = StringUtil::digitAt($tin, 0);
72
        $c2 = StringUtil::digitAt($tin, 1);
73
        $c3 = StringUtil::digitAt($tin, 2);
74
        $c4 = StringUtil::digitAt($tin, 3);
75
        $c5 = StringUtil::digitAt($tin, 4);
76
        $c6 = StringUtil::digitAt($tin, 5);
77
        $c7 = StringUtil::digitAt($tin, 6);
78
        $c8 = StringUtil::digitAt($tin, 7);
79
        $c9 = StringUtil::digitAt($tin, 8);
80
        $c10 = StringUtil::digitAt($tin, 9);
81
        $c11 = StringUtil::digitAt($tin, 10);
82
        $sum = $c1 * 3 + $c2 * 4 + $c3 * 5 + $c4 * 6 + $c5 * 7 + $c6 * 8 + $c7 * 9 + $c8 + $c9 * 2 + $c10 * 3;
83
        $remainderBy11 = $sum % 11;
84
        return ($remainderBy11 < 10 && $remainderBy11 == $c11) || ($remainderBy11 == 10 && $c11 == 0);
85
    }
86
87
    private function isValidDate(string $tin)
88
    {
89
        $year = intval(StringUtil::substring($tin, 1, 3));
90
        $month = intval(StringUtil::substring($tin, 3, 5));
91
        $day = intval(StringUtil::substring($tin, 5, 7));
92
        return DateUtil::validate(1900 + $year, $month, $day) || DateUtil::validate(2000 + $year, $month, $day);
93
    }
94
}
95