Passed
Push — master ( c02ff8...8cf6c5 )
by Esteban De La Fuente
06:05
created

DocumentSignatureStatusResponse::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 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 34
c 1
b 0
f 0
nc 33
nop 0
dl 0
loc 56
ccs 0
cts 42
cp 0
crap 56
rs 8.4426

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