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

SiiValidateDocumentResponse::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 0
Metric Value
eloc 32
dl 0
loc 54
c 0
b 0
f 0
ccs 0
cts 40
cp 0
rs 8.4746
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 de un DTE aceptado por el SII.
31
 *
32
 * Referencia: https://www.sii.cl/factura_electronica/factura_mercado/estado_dte.pdf
33
 */
34
class SiiValidateDocumentResponse 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' => 'Documento Recibido por el SII. Datos Coinciden con los Registrados.',
89
            '1' => 'Documento Recibido por el SII pero Datos NO Coinciden con los registrados.',
90
            '3' => 'Documento No Recibido por el SII.',
91
            '4' => 'Documento No Autorizado.',
92
            '5' => 'Documento Anulado.',
93
            '6' => 'Empresa no autorizada a Emitir Documentos Tributarios Electrónicos',
94
            '10' => 'Existe Nota de Debito que Modifica Texto Documento.',
95
            '11' => 'Existe Nota de Crédito que Modifica Textos Documento.',
96
            '12' => 'Existe Nota de Debito que Modifica Montos Documento.',
97
            '13' => 'Existe Nota de Crédito que Modifica Montos Documento.',
98
            '14' => 'Existe Nota de Debito que Anula Documento',
99
            '15' => 'Existe Nota de Crédito que Anula Documento Otro Error Interno.',
100
            //'OTRO' => '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
            );
143
144
            // Armar los datos normalizados.
145
            $this->data = [
146
                'query_number' => $number ?? null,
147
                'query_datetime' => $datetime ?? null,
148
                'company' => $company,
149
                'document' => $this->requestData['TipoDte'] ?? null,
150
                'number' => $this->requestData['FolioDte'] ?? null,
151
                'date' => $this->requestData['FechaEmisionDte'] ?? null,
152
                'total' => $this->requestData['MontoDte'] ?? null,
153
                'recipient' => $recipient,
154
                'status' => $status,
155
                'received' => $received,
156
                'description' => $description,
157
                'token' => $this->requestData['Token'] ?? null,
158
            ];
159
        }
160
161
        // Entregar los datos de la respuesta del estado del DTE.
162
        return $this->data;
163
    }
164
165
    /**
166
     * Parsea el estado de la respuesta del SII.
167
     *
168
     * @param array $headers Encabezados de la respuesta.
169
     * @return array Arreglo con el estado, error y descripción.
170
     */
171
    private function parseEstado(array $headers): array
172
    {
173
        // Asignar el código del estado y asumir que hubo error en la
174
        // validación del documento por parte del SII.
175
        $status = $headers['ESTADO'];
176
        $received = null;
177
        $description = null;
178
179
        // Verificar si el estado es uno de los estados "normales", o sea, no
180
        // es un estado de error en el envío. Se valida esto primero pues es lo
181
        // que normalmente debería entregar el SII en la respuesta.
182
        if (isset(self::STATUSES[$status])) {
183
            $received = !in_array($status[0], ['F', 'E']);
184
            $description = $headers['GLOSA_ERR'] ?? null;
185
        }
186
187
        // Si el estado es un error de token se asigna.
188
        elseif (isset(self::ERRORS['TOKEN'][$status])) {
189
            //$description = self::ERRORS['TOKEN'][$code];
190
            $description = $headers['GLOSA'] ?? null;
191
        }
192
193
        // El error es uno de los definidos como error de estado (excepto -11).
194
        elseif (isset(self::ERRORS['ESTADO'][$status])) {
195
            $description = self::ERRORS['ESTADO'][$status];
196
        }
197
198
        // El error es de estado pero no se tiene el código de error registrado.
199
        else {
200
            $description = sprintf(
201
                'Error desconocido código #%s al subir el XML.',
202
                $status
203
            );
204
        }
205
206
        // Entregar valores determinados para el error.
207
        return [$status, $received, $description];
208
    }
209
}
210