Skip to content

Commit

Permalink
Se agrega idea para parsers de los datos de entrada de un DTE (wip).
Browse files Browse the repository at this point in the history
  • Loading branch information
estebandelaf committed Dec 13, 2024
1 parent 1e61c5a commit 66ce43f
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 0 deletions.
136 changes: 136 additions & 0 deletions src/Sii/Dte/Documento/Parser/DocumentoParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser;

/**
* Clase que maneja el análisis sintáctico de los datos de un documento.
*
* Se encarga de tomar los datos en cierto formato y transformarlos a un formato
* estándarizado para ser usado en LibreDTE como un arreglo PHP con los datos en
* la estructura oficial del SII.
*/
class DocumentoParser
{
/**
* Parser por defecto que se debe utilizar al analizar los datos si no se
* ha especificado uno al llamar al método DocumentoParser::parse().
*
* @var string
*/
protected string $defaultParser = 'sii.json';

/**
* Alias de parsers.
*
* Esto es por compatibilidad hacia atrás y simplificación en el uso de los
* parsers estándares de LibreDTE que usan el formato oficial del SII.
*
* @var array
*/
protected array $parsersAlias = [
'json' => 'sii.json',
'yaml' => 'sii.yaml',
'xml' => 'sii.xml',
];

/**
* Listado de parsers instanciados para ser reutilizados.
*
* @var array<string,DocumentoParserInterface>
*/
protected array $parsers = [];

/**
* Ejecuta el análisis sintáctico (parseo) de los datos.
*
* @param string|array $data Datos del documento a transformar.
* @return array Arreglo con los datos transformados.
* @throws DocumentoParserException Si existe un error al parsear los datos.
*/
public function parse(string|array $data, string $parser = null): array
{
// Si no se indicó parser se usa el por defecto.
if ($parser === null) {
$parser = $this->defaultParser;
}

// Si el parser es un alias se ajusta el nombre del parser al real.
if (isset($this->parsersAlias[$parser])) {
$parser = $this->parsersAlias[$parser];
}

// Obtener la instancia del parser real.
$parser = $this->getParserInstance($parser);

// Llamar al parser para transformar los datos.
$parsedData = $parser->parse($data);

// Entregar los datos transformados.
return $parsedData;
}

/**
* Obtiene la instancia de un parser.
*
* @param string $parser Nombre del parser que se desea obtener.
* @return DocumentoParserInterface Instancia del parser.
*/
private function getParserInstance(string $parser): DocumentoParserInterface
{
// Si el parser no está previamente cargado se carga.
if (!isset($this->parsers[$parser])) {
// Determinar la clase del parser solicitado.
$class = $this->getParserClass($parser);

// Si la clase del parser no existe error.
if (!class_exists($class)) {
throw new DocumentoParserException(sprintf(
'El analizador sintáctico (parser) con el formato %s no existe.',
$parser
));
}

// Instanciar el parser.
$this->parsers[$parser] = new $class;
}

// Entregar la instancia del parser.
return $this->parsers[$parser];
}

/**
* Determina la clase del parser que se está solicitando.
*
* @param string $parser Nombre del parser solicitado.
* @return string FQCN de la clase del parser solicitado.
*/
private function getParserClass(string $parser): string
{
// TODO: Determinar la clase del parser.
$class = '';

return $class;
}
}
35 changes: 35 additions & 0 deletions src/Sii/Dte/Documento/Parser/DocumentoParserException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser;

use Exception;

/**
* Excepción personalizada para errores asociados al análisis sintáctico de los
* datos de entrada de un documento tributario electrónico.
*/
class DocumentoParserException extends Exception
{
}
39 changes: 39 additions & 0 deletions src/Sii/Dte/Documento/Parser/DocumentoParserInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser;

/**
* Interfaz para los parsers de datos de entrada de los documentos tributarios.
*/
interface DocumentoParserInterface
{
/**
* Realiza la transformación de los datos del documento.
*
* @param string $data Datos de entrada del formato original.
* @return array Arreglo transformado a la estructura oficial del SII.
*/
public function parse(string $data): array;
}
47 changes: 47 additions & 0 deletions src/Sii/Dte/Documento/Parser/Sii/Json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser\Sii;

use libredte\lib\Core\Sii\Dte\Documento\Parser\DocumentoParserInterface;

/**
* Transforma los datos en formato JSON con la estructura oficial del SII a un
* arreglo PHP con la estructura oficial del SII.
*/
class JsonParser implements DocumentoParserInterface
{
/**
* Realiza la transformación de los datos del documento.
*
* @param string $data JSON con los datos de entrada.
* @return array Arreglo transformado a la estructura oficial del SII.
*/
public function parse(string $data): array
{
$array = json_decode($data, true);

return $array;
}
}
71 changes: 71 additions & 0 deletions src/Sii/Dte/Documento/Parser/Sii/Xml.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser\Sii;

use libredte\lib\Core\Sii\Dte\Documento\Parser\DocumentoParserException;
use libredte\lib\Core\Sii\Dte\Documento\Parser\DocumentoParserInterface;
use libredte\lib\Core\Xml\XmlConverter;
use libredte\lib\Core\Xml\XmlDocument;

/**
* Transforma los datos en formato XML con la estructura oficial del SII a un
* arreglo PHP con la estructura oficial del SII.
*/
class XmlParser implements DocumentoParserInterface
{
/**
* Realiza la transformación de los datos del documento.
*
* @param string $data XML con los datos de entrada.
* @return array Arreglo transformado a la estructura oficial del SII.
*/
public function parse(string $data): array
{
// Cargar los datos del XML a un arreglo.
$xmlDocument = new XmlDocument();
$xmlDocument->loadXML($data);
$array = XmlConverter::xmlToArray($xmlDocument);

// Obtener los datos del documento a generar.
$documentoData = $array['DTE']['Documento']
?? $array['DTE']['Exportaciones']
?? $array['DTE']['Liquidacion']
?? null
;

// Si el XML no tiene los tags válidos se lanza una excepción.
if ($documentoData === null) {
throw new DocumentoParserException(
'El nodo raíz del XML del documento debe ser el tag "DTE". Dentro de este nodo raíz debe existir un tag "Documento", "Exportaciones" o "Liquidacion". Este segundo nodo es el que debe contener los datos del documento.'
);
}

// Quitar los atributos que tenga el tag encontrado.
unset($documentoData['@attributes']);

// Entregar los datos parseados.
return $documentoData;
}
}
48 changes: 48 additions & 0 deletions src/Sii/Dte/Documento/Parser/Sii/Yaml.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

/**
* LibreDTE: Biblioteca PHP (Núcleo).
* Copyright (C) LibreDTE <https://www.libredte.cl>
*
* Este programa es software libre: usted puede redistribuirlo y/o modificarlo
* bajo los términos de la Licencia Pública General Affero de GNU publicada
* por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
* o (a su elección) cualquier versión posterior de la misma.
*
* Este programa se distribuye con la esperanza de que sea útil, pero SIN
* GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
* PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
* General Affero de GNU para obtener una información más detallada.
*
* Debería haber recibido una copia de la Licencia Pública General Affero de
* GNU junto a este programa.
*
* En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
*/

namespace libredte\lib\Core\Sii\Dte\Documento\Parser\Sii;

use libredte\lib\Core\Sii\Dte\Documento\Parser\DocumentoParserInterface;
use Symfony\Component\Yaml\Yaml;

/**
* Transforma los datos en formato YAML con la estructura oficial del SII a un
* arreglo PHP con la estructura oficial del SII.
*/
class YamlParser implements DocumentoParserInterface
{
/**
* Realiza la transformación de los datos del documento.
*
* @param string $data YAML con los datos de entrada.
* @return array Arreglo transformado a la estructura oficial del SII.
*/
public function parse(string $data): array
{
$array = Yaml::parse($data);

return $array;
}
}

0 comments on commit 66ce43f

Please sign in to comment.