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

ValidateDocumentJob::validate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 69
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
dl 0
loc 69
c 1
b 0
f 0
ccs 0
cts 47
cp 0
rs 9.248
cc 3
nc 3
nop 7
crap 12

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\Worker\SiiLazy\Job;
26
27
use Derafu\Lib\Core\Foundation\Abstract\AbstractJob;
28
use Derafu\Lib\Core\Foundation\Contract\JobInterface;
29
use Derafu\Lib\Core\Helper\Date;
30
use Derafu\Lib\Core\Helper\Rut;
31
use Derafu\Lib\Core\Package\Prime\Component\Xml\Contract\XmlComponentInterface;
32
use libredte\lib\Core\Package\Billing\Component\Integration\Contract\SiiRequestInterface;
33
use libredte\lib\Core\Package\Billing\Component\Integration\Exception\SiiConsumeWebserviceException;
34
use libredte\lib\Core\Package\Billing\Component\Integration\Exception\SiiValidateDocumentException;
35
use libredte\lib\Core\Package\Billing\Component\Integration\Support\Response\SiiValidateDocumentResponse;
36
37
/**
38
 * Clase para el envío de documentos al SII.
39
 *
40
 * Principalmente es para el envío y consulta de estado del envío de documentos
41
 * tributarios electrónicos en formato XML.
42
 */
43
class ValidateDocumentJob extends AbstractJob implements JobInterface
44
{
45
    public function __construct(
46
        private AuthenticateJob $authenticateJob,
47
        private ConsumeWebserviceJob $consumeWebserviceJob,
48
        private XmlComponentInterface $xmlComponent
49
    ) {
50
    }
51
52
    /**
53
     * Obtiene el estado de un documento en el SII.
54
     *
55
     * Este estado solo se obtiene si el documento se encuentra aceptado por el
56
     * SII, ya sea aceptado 100% OK o con reparos.
57
     *
58
     * Este servicio valida que el documento exista en SII (esté aceptado) y
59
     * además que los datos del documento proporcionados coincidan.
60
     *
61
     * Referencia: https://www.sii.cl/factura_electronica/factura_mercado/estado_dte.pdf
62
     *
63
     * @param SiiRequestInterface $request Datos de la solicitud al SII.
64
     * @param string $company RUT de la empresa emisora del documento.
65
     * @param int $document Tipo de documento tributario electrónico.
66
     * @param int $number Folio del documento.
67
     * @param string $date Fecha de emisión del documento, formato: AAAA-MM-DD.
68
     * @param int $total Total del documento.
69
     * @param string $recipient RUT del receptor del documento.
70
     * @return SiiValidateDocumentResponse
71
     * @throws SiiValidateDocumentException En caso de error.
72
     */
73
    public function validate(
74
        SiiRequestInterface $request,
75
        string $company,
76
        int $document,
77
        int $number,
78
        string $date,
79
        int $total,
80
        string $recipient
81
    ): SiiValidateDocumentResponse {
82
        // Validar los RUT que se utilizarán para la consulta de estado del DTE.
83
        $user = $request->getCertificate()->getId();
84
        Rut::validate($user);
85
        Rut::validate($company);
86
        Rut::validate($recipient);
87
        [$rutUser, $dvUser] = Rut::toArray($user);
88
        [$rutCompany, $dvCompany] = Rut::toArray($company);
89
        [$rutRecipient, $dvRecipient] = Rut::toArray($recipient);
90
91
        // Validar fecha y convertir al formato del SII.
92
        $dateSii = Date::validateAndConvert($date, 'dmY');
93
        if ($dateSii === null) {
94
            throw new SiiValidateDocumentException(sprintf(
95
                'La fecha %s del documento no es válida, debe tener formato AAAA-MM-DD.',
96
                $date
97
            ));
98
        }
99
100
        // Obtener el token asociado al certificado digital.
101
        $token = $this->authenticateJob->authenticate($request);
102
103
        // Datos para la consulta.
104
        $requestData = [
105
            'RutConsultante' => $rutUser,
106
            'DvConsultante' => $dvUser,
107
            'RutCompania' => $rutCompany,
108
            'DvCompania' => $dvCompany,
109
            'RutReceptor' => $rutRecipient,
110
            'DvReceptor' => $dvRecipient,
111
            'TipoDte' => $document,
112
            'FolioDte' => $number,
113
            'FechaEmisionDte' => $dateSii,
114
            'MontoDte' => $total,
115
            'Token' => $token,
116
        ];
117
118
        // Consultar el estado del documento al SII.
119
        try {
120
            $xmlResponse = $this->consumeWebserviceJob->sendRequest(
121
                $request,
122
                'QueryEstDte',
123
                'getEstDte',
124
                $requestData
125
            );
126
        } catch (SiiConsumeWebserviceException $e) {
127
            throw new SiiValidateDocumentException(sprintf(
128
                'No fue posible obtener el estado del documento T%dF%d de %d-%s desde el SII. %s',
129
                $document,
130
                $number,
131
                $rutCompany,
132
                $dvCompany,
133
                $e->getMessage()
134
            ));
135
        }
136
137
        // Armar estado del XML enviado y retornar.
138
        $responseData = $this->xmlComponent->getDecoderWorker()->decode(
139
            $xmlResponse
140
        );
141
        return new SiiValidateDocumentResponse($responseData, $requestData);
142
    }
143
}
144