PLAlgorithm::isFollowPattern2()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
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
 * Poland
10
 */
11
class PLAlgorithm extends TINAlgorithm
12
{
13
    const LENGTH_1 = 10;
14
    const PATTERN_1 = "\\d{10}";
15
    const LENGTH_2 = 11;
16
    const PATTERN_2 = "\\d{11}";
17
18
    public function validate(string $tin)
19
    {
20
        if (!$this->isFollowLength1($tin) && !$this->isFollowLength2($tin)) {
21
            return StatusCode::INVALID_LENGTH;
22
        }
23
        if (!$this->isFollowPatterns($tin)) {
24
            return StatusCode::INVALID_PATTERN;
25
        }
26
        if (!$this->isFollowRules($tin)) {
27
            return StatusCode::INVALID_SYNTAX;
28
        }
29
        return StatusCode::VALID;
30
    }
31
32
    public function isFollowRules(string $tin)
33
    {
34
        return ($this->isFollowLength1($tin) && $this->isFollowRulePoland1($tin)) || ($this->isFollowLength2($tin) && $this->isFollowRulePoland2($tin));
35
    }
36
37
    public function isFollowPatterns(string $tin)
38
    {
39
        return $this->isFollowLength1AndPattern1($tin) || $this->isFollowLength2AndPattern2AndIsValidDate($tin);
40
    }
41
42
    public function isFollowLength1AndPattern1(string $tin)
43
    {
44
        return $this->isFollowLength1($tin) && $this->isFollowPattern1($tin);
45
    }
46
47
    public function isFollowLength2AndPattern2AndIsValidDate(string $tin)
48
    {
49
        return $this->isFollowLength2($tin) && $this->isFollowPattern2($tin) && $this->isValidDate($tin);
50
    }
51
52
    public function isFollowLength1(string $tin)
53
    {
54
        return StringUtil::isFollowLength($tin, self::LENGTH_1);
55
    }
56
57
    public function isFollowPattern1(string $tin)
58
    {
59
        return StringUtil::isFollowPattern($tin, self::PATTERN_1);
60
    }
61
62
    public function isFollowLength2(string $tin)
63
    {
64
        return StringUtil::isFollowLength($tin, self::LENGTH_2);
65
    }
66
67
    public function isFollowPattern2(string $tin)
68
    {
69
        return StringUtil::isFollowPattern($tin, self::PATTERN_2);
70
    }
71
72
    private function isFollowRulePoland1(string $tin)
73
    {
74
        $c1 = StringUtil::digitAt($tin, 0);
75
        $c2 = StringUtil::digitAt($tin, 1);
76
        $c3 = StringUtil::digitAt($tin, 2);
77
        $c4 = StringUtil::digitAt($tin, 3);
78
        $c5 = StringUtil::digitAt($tin, 4);
79
        $c6 = StringUtil::digitAt($tin, 5);
80
        $c7 = StringUtil::digitAt($tin, 6);
81
        $c8 = StringUtil::digitAt($tin, 7);
82
        $c9 = StringUtil::digitAt($tin, 8);
83
        $c10 = StringUtil::digitAt($tin, 9);
84
        $sum = $c1 * 6 + $c2 * 5 + $c3 * 7 + $c4 * 2 + $c5 * 3 + $c6 * 4 + $c7 * 5 + $c8 * 6 + $c9 * 7;
85
        $remainderBy11 = $sum % 11;
86
        if ($remainderBy11 == 10) {
87
            return false;
88
        }
89
        return $c10 == $remainderBy11;
90
    }
91
92
    private function isFollowRulePoland2(string $tin)
93
    {
94
        $c1 = StringUtil::digitAt($tin, 0);
95
        $c2 = StringUtil::digitAt($tin, 1);
96
        $c3 = StringUtil::digitAt($tin, 2);
97
        $c4 = StringUtil::digitAt($tin, 3);
98
        $c5 = StringUtil::digitAt($tin, 4);
99
        $c6 = StringUtil::digitAt($tin, 5);
100
        $c7 = StringUtil::digitAt($tin, 6);
101
        $c8 = StringUtil::digitAt($tin, 7);
102
        $c9 = StringUtil::digitAt($tin, 8);
103
        $c10 = StringUtil::digitAt($tin, 9);
104
        $c11 = StringUtil::digitAt($tin, 10);
105
        $sum = $c1 * 1 + $c2 * 3 + $c3 * 7 + $c4 * 9 + $c5 * 1 + $c6 * 3 + $c7 * 7 + $c8 * 9 + $c9 * 1 + $c10 * 3;
106
        $lastDigit = $sum % 10;
107
        return $c11 == 10 - $lastDigit;
108
    }
109
110
    private function isValidDate(string $tin)
111
    {
112
        $year = intval(StringUtil::substring($tin, 0, 2));
113
        $month = intval(StringUtil::substring($tin, 2, 4));
114
        $day = intval(StringUtil::substring($tin, 4, 6));
115
        if ($month >= 1 && $month <= 12) {
116
            return DateUtil::validate(1900 + $year, $month, $day);
117
        }
118
        if ($month >= 21 && $month <= 32) {
119
            return DateUtil::validate(2000 + $year, $month - 20, $day);
120
        }
121
        if ($month >= 41 && $month <= 52) {
122
            return DateUtil::validate(2100 + $year, $month - 40, $day);
123
        }
124
        if ($month >= 61 && $month <= 72) {
125
            return DateUtil::validate(2200 + $year, $month - 60, $day);
126
        }
127
        return $month >= 81 && $month <= 92 && DateUtil::validate(1800 + $year, $month - 80, $day);
128
    }
129
}
130