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

DocumentStatusResponse::getData()   B

Complexity

Conditions 7
Paths 33

Size

Total Lines 54
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 32
c 1
b 0
f 0
nc 33
nop 0
dl 0
loc 54
ccs 0
cts 40
cp 0
crap 56
rs 8.4746

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 de un DTE aceptado por el SII.
29
 *
30
 * Referencia: https://www.sii.cl/factura_electronica/factura_mercado/estado_dte.pdf
31
 */
32
class DocumentStatusResponse 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' => 'Documento Recibido por el SII. Datos Coinciden con los Registrados.',
87
            '1' => 'Documento Recibido por el SII pero Datos NO Coinciden con los registrados.',
88
            '3' => 'Documento No Recibido por el SII.',
89
            '4' => 'Documento No Autorizado.',
90
            '5' => 'Documento Anulado.',
91
            '6' => 'Empresa no autorizada a Emitir Documentos Tributarios Electrónicos',
92
            '10' => 'Existe Nota de Debito que Modifica Texto Documento.',
93
            '11' => 'Existe Nota de Crédito que Modifica Textos Documento.',
94
            '12' => 'Existe Nota de Debito que Modifica Montos Documento.',
95
            '13' => 'Existe Nota de Crédito que Modifica Montos Documento.',
96
            '14' => 'Existe Nota de Debito que Anula Documento',
97
            '15' => 'Existe Nota de Crédito que Anula Documento Otro Error Interno.',
98
            //'OTRO' => 'Error Interno.',
99
        ],
100
    ];
101
102
    /**
103
     * Obtiene los datos normalizados de la respuesta.
104
     *
105
     * @return array Datos normalizados de la respuesta del SII.
106
     */
107
    public function getData(): array
108
    {
109
        // Si no existen los datos normalizados de la respuesta se normalizan.
110
        if (!isset($this->data)) {
111
            // Si hay número de atención se normaliza.
112
            [$number, $datetime] = !empty($this->headers['NUM_ATENCION'])
113
                ? $this->parseNumeroAtencion($this->headers['NUM_ATENCION'])
114
                : null
115
            ;
116
117
            // RUT de la empresa emisora del documento.
118
            $rutExists = isset($this->requestData['RutCompania'])
119
                && isset($this->requestData['DvCompania'])
120
            ;
121
            $company = $rutExists
122
                ? $this->requestData['RutCompania']
123
                    . '-' . $this->requestData['DvCompania']
124
                : null
125
            ;
126
127
            // RUT del receptor del documento.
128
            $rutExists = isset($this->requestData['RutReceptor'])
129
                && isset($this->requestData['DvReceptor'])
130
            ;
131
            $recipient = $rutExists
132
                ? $this->requestData['RutReceptor']
133
                    . '-' . $this->requestData['DvReceptor']
134
                : null
135
            ;
136
137
            // Normalizar el estado de la consulta del envío.
138
            [$status, $received, $description] = $this->parseEstado(
139
                $this->headers
140
            );
141
142
            // Armar los datos normalizados.
143
            $this->data = [
144
                'query_number' => $number ?? null,
145
                'query_datetime' => $datetime ?? null,
146
                'company' => $company,
147
                'document' => $this->requestData['TipoDte'] ?? null,
148
                'number' => $this->requestData['FolioDte'] ?? null,
149
                'date' => $this->requestData['FechaEmisionDte'] ?? null,
150
                'total' => $this->requestData['MontoDte'] ?? null,
151
                'recipient' => $recipient,
152
                'status' => $status,
153
                'received' => $received,
154
                'description' => $description,
155
                'token' => $this->requestData['Token'] ?? null,
156
            ];
157
        }
158
159
        // Entregar los datos de la respuesta del estado del DTE.
160
        return $this->data;
161
    }
162
163
    /**
164
     * Parsea el estado de la respuesta del SII.
165
     *
166
     * @param array $headers Encabezados de la respuesta.
167
     * @return array Arreglo con el estado, error y descripción.
168
     */
169
    private function parseEstado(array $headers): array
170
    {
171
        // Asignar el código del estado y asumir que hubo error en la
172
        // validación del documento por parte del SII.
173
        $status = $headers['ESTADO'];
174
        $received = null;
175
        $description = null;
176
177
        // Verificar si el estado es uno de los estados "normales", o sea, no
178
        // es un estado de error en el envío. Se valida esto primero pues es lo
179
        // que normalmente debería entregar el SII en la respuesta.
180
        if (isset(self::STATUSES[$status])) {
181
            $received = !in_array($status[0], ['F', 'E']);
182
            $description = $headers['GLOSA_ERR'] ?? null;
183
        }
184
185
        // Si el estado es un error de token se asigna.
186
        elseif (isset(self::ERRORS['TOKEN'][$status])) {
187
            //$description = self::ERRORS['TOKEN'][$code];
188
            $description = $headers['GLOSA'] ?? null;
189
        }
190
191
        // El error es uno de los definidos como error de estado (excepto -11).
192
        elseif (isset(self::ERRORS['ESTADO'][$status])) {
193
            $description = self::ERRORS['ESTADO'][$status];
194
        }
195
196
        // El error es de estado pero no se tiene el código de error registrado.
197
        else {
198
            $description = sprintf(
199
                'Error desconocido código #%s al subir el XML.',
200
                $status
201
            );
202
        }
203
204
        // Entregar valores determinados para el error.
205
        return [$status, $received, $description];
206
    }
207
}
208