Passed
Branch develop (477450)
by JAIME ELMER
06:26
created

InputValidator::getValidations()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 5
nc 5
nop 0
dl 0
loc 6
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * MÓDULO DE EMISIÓN ELECTRÓNICA F72X
5
 * UBL 2.1
6
 * Version 1.1
7
 * 
8
 * Copyright 2018, Jaime Cruz
9
 */
10
11
namespace F72X\Sunat;
12
13
use F72X\Sunat\Catalogo;
14
use F72X\Tools\Validations;
15
16
class InputValidator {
17
18
    private $data;
19
    private $type;
20
    private static $invoiceValidations = [
21
        'currencyCode' => [
22
            'required' => true,
23
            'inCat' => Catalogo::CAT_CURRENCY_TYPE
24
        ],
25
        'operationType' => [
26
            'required' => true,
27
            'inCat' => Catalogo::CAT_FACTURA_TYPE
28
        ],
29
        'documentSeries' => [
30
            'required' => true
31
        ],
32
        'documentNumber' => [
33
            'required' => true
34
        ],
35
        'issueDate' => [
36
            'required' => true
37
        ],
38
        'customerDocType' => [
39
            'required' => true,
40
            'inCat' => Catalogo::CAT_IDENT_DOCUMENT_TYPE
41
        ],
42
        'customerDocNumber' => [
43
            'required' => true
44
        ],
45
        'customerRegName' => [
46
            'required' => true
47
        ],
48
        'items' => [
49
            'required' => true,
50
            'type' => 'Array'
51
        ]
52
    ];
53
54
    private static $creditNoteValidations = [
55
        'currencyCode' => [
56
            'required' => true,
57
            'inCat' => Catalogo::CAT_CURRENCY_TYPE
58
        ],
59
        'documentSeries' => [
60
            'required' => true
61
        ],
62
        'documentNumber' => [
63
            'required' => true
64
        ],
65
        'issueDate' => [
66
            'required' => true
67
        ],
68
        'customerDocType' => [
69
            'required' => true,
70
            'inCat' => Catalogo::CAT_IDENT_DOCUMENT_TYPE
71
        ],
72
        'customerDocNumber' => [
73
            'required' => true
74
        ],
75
        'customerRegName' => [
76
            'required' => true
77
        ],
78
        'items' => [
79
            'required' => true,
80
            'type' => 'Array'
81
        ]
82
    ];
83
    
84
    private $errors = [];
85
86
    public function __construct(array $data, $type) {
87
        $this->data = $data;
88
        $this->type = $type;
89
        $this->validate();
90
    }
91
92
    public function isValid() {
93
        return empty($this->errors);
94
    }
95
96
    public function getErrors() {
97
        return $this->errors;
98
    }
99
100
    private function validate() {
101
        $validations = $this->getValidations();
102
        foreach ($validations as $field => $item) {
103
            $defauls = [
104
                'required' => false,
105
                'type' => null,
106
                'incat' => null
107
            ];
108
            $validation = array_merge($defauls, $item);
109
            if ($field == 'customerDocNumber') {
110
                $validation['type'] = $this->getDocTypeValidator();
111
            }
112
            $this->validateItem($field, $validation);
113
        }
114
    }
115
116
    private function getValidations() {
117
        switch ($this->type) {
118
            case Catalogo::DOCTYPE_FACTURA      :
119
            case Catalogo::DOCTYPE_BOLETA       : return self::$invoiceValidations;
120
            case Catalogo::DOCTYPE_NOTA_CREDITO : return self::$creditNoteValidations;
121
            case Catalogo::DOCTYPE_NOTA_DEBITO  : return self::$creditNoteValidations;
122
        }
123
    }
124
    private function validateItem($field, $validation) {
125
        $data = $this->data;
126
        $fieldExist = isset($data[$field]);
127
        $fieldValue = $fieldExist ? $data[$field] : null;
128
129
        $required = $validation['required'];
130
        $catNumber = $validation['incat'];
131
        $type = $validation['type'];
132
        // Required
133
        if ($required && !$fieldExist) {
134
            $this->errors[] = "$field es requerido.";
135
        }
136
        if (!$fieldExist) {
137
            return;
138
        }
139
        // Data type
140
        if ($type && !Validations::{'is' . $type}($fieldValue)) {
141
            $this->errors[] = $this->getTypeErrorValidationMessage($field, $fieldValue, $type);
142
        }
143
        // In catalog
144
        if ($catNumber && !Catalogo::itemExist($catNumber, $fieldValue)) {
145
            $this->errors[] = "El valor $fieldValue en el campo $field no existe en el Cátalogo N° $catNumber.";
146
        }
147
    }
148
149
    private function getTypeErrorValidationMessage($field, $value, $type) {
150
        switch ($type) {
151
            case 'Array':
152
                return $field == 'items' ?
153
                    'El campo items debe ser de tipo array.' : "Se espera que el campo $field sea un array.";
154
            case 'Dni':
155
                return "$value no es un DNI valido.";
156
            case 'Ruc':
157
                return "$value no es un DUC valido.";
158
            default:
159
                break;
160
        }
161
    }
162
163
    private function getDocTypeValidator() {
164
        $data = $this->data;
165
        $docType = isset($data['customerDocType']) ? $data['customerDocType'] : null;
166
        return is_null($docType) ? null : $this->getDocType($docType);
167
    }
168
169
    private function getDocType($docType) {
170
        // @IMP cases: 0, 7, A, B, C, D, E
171
        $cases = [
172
            '1' => 'Dni',
173
            '6' => 'Ruc'
174
        ];
175
        return isset($cases[$docType]) ? $cases[$docType] : null;
176
    }
177
178
}
179