Passed
Push — master ( 9d79d3...4bb85e )
by Esteban De La Fuente
08:41
created

SiiValidateDocumentSignatureResponse::getData()   B

Complexity

Conditions 7
Paths 33

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 56
c 0
b 0
f 0
ccs 0
cts 42
cp 0
rs 8.4426
cc 7
nc 33
nop 0
crap 56

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * LibreDTE: Biblioteca PHP (Núcleo).
7
 * Copyright (C) LibreDTE <https://www.libredte.cl>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de
20
 * GNU junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace libredte\lib\Core\Package\Billing\Component\Integration\Support\Response;
26
27
use libredte\lib\Core\Package\Billing\Component\Integration\Abstract\AbstractSiiWsdlResponse;
28
29
/**
30
 * Respuesta con el estado avanzado de un DTE aceptado por el SII.
31
 *
32
 * Referencia: https://www.sii.cl/factura_electronica/factura_mercado/OIFE2006_QueryEstDteAv_MDE.pdf
33
 */
34
class SiiValidateDocumentSignatureResponse extends AbstractSiiWsdlResponse
35
{
36
    /**
37
     * Estados de salida.
38
     *
39
     * El resultado de la consulta al SII puede arrojar uno de estos estados.
40
     */
41
    private const STATUSES = [
42
        'DOK' => 'Documento Recibido por el SII. Datos Coinciden con los Registrados.',
43
        'DNK' => 'Documento Recibido por el SII pero Datos NO Coinciden con los registrados.',
44
        'FAU' => 'Documento No Recibido por el SII.',
45
        'FNA' => 'Documento No Autorizado.',
46
        'FAN' => 'Documento Anulado.',
47
        'EMP' => 'Empresa no autorizada a Emitir Documentos Tributarios Electrónicos',
48
        'TMD' => 'Existe Nota de Débito que Modifica Texto Documento.',
49
        'TMC' => 'Existe Nota de Crédito que Modifica Textos Documento.',
50
        'MMD' => 'Existe Nota de Débito que Modifica Montos Documento.',
51
        'MMC' => 'Existe Nota de Crédito que Modifica Montos Documento.',
52
        'AND' => 'Existe Nota de Débito que Anula Documento',
53
        'ANC' => 'Existe Nota de Crédito que Anula Documento',
54
    ];
55
56
    /**
57
     * Estados de salida por ERROR.
58
     *
59
     * El resultado de la consulta al SII puede arrojar uno de estos estados de
60
     * error.
61
     */
62
    private const ERRORS = [
63
        // Otros Errores.
64
        'ESTADO' => [
65
            '-1' => 'ERROR: RETORNO CAMPO ESTADO',
66
            '-2' => 'ERROR RETORNO',
67
            '-3' => 'ERROR RETORNO',
68
            '-4' => 'ERROR RETORNO',
69
            //'OTRO' => 'No documentado.',
70
        ],
71
        // Errores por autenticación.
72
        'TOKEN' => [
73
            '001' => 'Cookie Inactivo (o token no existe)',
74
            '002' => 'Token Inactivo',
75
            '003' => 'Token No Existe',
76
        ],
77
        // Errores de consulta.
78
        'SRV_CODE' => [
79
            0 => 'Todo Ok',
80
            1 => 'Error en Entrada',
81
            2 => 'Error SQL',
82
        ],
83
        'SQL_CODE' => [
84
            0 => 'Schema Validado',
85
            //'OTRO' => 'Código de Oracle',
86
        ],
87
        'ERR_CODE' => [
88
            '0' => 'Consulta procesada OK.',
89
            '1' => 'Token inactivo (expirado)',
90
            '2' => 'Token no existe',
91
            '3' => 'Error Interno (ver glosa)',
92
            '4' => 'Error Interno',
93
            '5' => 'Error parámetros de entrada (ver glosa)',
94
            '6' => 'Error Interno',
95
            '7' => 'Error Interno',
96
            '8' => 'Error Interno',
97
            '9' => 'Usuario no autorizado en empresa',
98
            '10' => 'Error Interno',
99
            '11' => 'Error Interno',
100
            '12' => 'Error Interno',
101
            '13' => 'Error Interno',
102
            '14' => 'Error Interno',
103
        ],
104
    ];
105
106
    /**
107
     * Obtiene los datos normalizados de la respuesta.
108
     *
109
     * @return array Datos normalizados de la respuesta del SII.
110
     */
111
    public function getData(): array
112
    {
113
        // Si no existen los datos normalizados de la respuesta se normalizan.
114
        if (!isset($this->data)) {
115
            // Si hay número de atención se normaliza.
116
            [$number, $datetime] = !empty($this->headers['NUM_ATENCION'])
117
                ? $this->parseNumeroAtencion($this->headers['NUM_ATENCION'])
118
                : null
119
            ;
120
121
            // RUT de la empresa emisora del documento.
122
            $rutExists = isset($this->requestData['RutCompania'])
123
                && isset($this->requestData['DvCompania'])
124
            ;
125
            $company = $rutExists
126
                ? $this->requestData['RutCompania']
127
                    . '-' . $this->requestData['DvCompania']
128
                : null
129
            ;
130
131
            // RUT del receptor del documento.
132
            $rutExists = isset($this->requestData['RutReceptor'])
133
                && isset($this->requestData['DvReceptor'])
134
            ;
135
            $recipient = $rutExists
136
                ? $this->requestData['RutReceptor']
137
                    . '-' . $this->requestData['DvReceptor']
138
                : null
139
            ;
140
141
            // Normalizar el estado de la consulta del envío.
142
            [$status, $received, $description] = $this->parseEstado(
143
                $this->headers,
144
                $this->body
145
            );
146
147
            // Armar los datos normalizados.
148
            $this->data = [
149
                'query_number' => $number ?? null,
150
                'query_datetime' => $datetime ?? null,
151
                'company' => $company,
152
                'document' => $this->requestData['TipoDte'] ?? null,
153
                'number' => $this->requestData['FolioDte'] ?? null,
154
                'date' => $this->requestData['FechaEmisionDte'] ?? null,
155
                'total' => $this->requestData['MontoDte'] ?? null,
156
                'signature' => $this->requestData['FirmaDte'] ?? null,
157
                'recipient' => $recipient,
158
                'status' => $status,
159
                'received' => $received,
160
                'description' => $description,
161
                'token' => $this->requestData['Token'] ?? null,
162
            ];
163
        }
164
165
        // Entregar los datos de la respuesta del estado del DTE.
166
        return $this->data;
167
    }
168
169
    /**
170
     * Parsea el estado de la respuesta del SII.
171
     *
172
     * @param array $headers Encabezados de la respuesta.
173
     * @param array $body Cuerpo de la respuesta.
174
     * @return array Arreglo con el estado, error y descripción.
175
     */
176
    private function parseEstado(array $headers, array $body): array
177
    {
178
        // Asignar el código del estado y asumir que hubo error en la
179
        // validación del documento por parte del SII.
180
        $status = $headers['ESTADO'] ?? $body['ESTADO'] ?? $headers['SII:ESTADO'];
181
        $received = ($body['RECIBIDO'] ?? 'NO') === 'SI';
182
        $description = null;
183
184
        // Verificar si el estado es uno de los estados "normales", o sea, no
185
        // es un estado de error en el envío. Se valida esto primero pues es lo
186
        // que normalmente debería entregar el SII en la respuesta.
187
        if (isset(self::STATUSES[$status])) {
188
            $description = $headers['GLOSA_ERR'] ?? null;
189
        }
190
191
        // Si el estado es un error de token se asigna.
192
        elseif (isset(self::ERRORS['TOKEN'][$status])) {
193
            //$description = self::ERRORS['TOKEN'][$code];
194
            $description = $headers['SII:GLOSA'] ?? null;
195
        }
196
197
        // El error es uno de los definidos como error de estado (excepto -11).
198
        elseif (isset(self::ERRORS['ESTADO'][$status])) {
199
            $description = self::ERRORS['ESTADO'][$status];
200
        }
201
202
        // El error es de estado pero no se tiene el código de error registrado.
203
        else {
204
            $description = sprintf(
205
                'Error desconocido código #%s al subir el XML.',
206
                $status
207
            );
208
        }
209
210
        // Entregar valores determinados para el error.
211
        return [$status, $received, $description];
212
    }
213
}
214