Skip to content

Commit b0f4a5d

Browse files
committed
Se modificaron los workflow ci.yml y -scrutinizer.yml para incluir algunos tests nuevos. Se reestructuró en gran medida la carpeta de tests. Se añadieron tests nuevos relacionados con DTEs reales, temporales y recibidos, además de 3 tests para pagos y cobros masivos. Se estandarizaron formatos de strings, largos de código y largos de documentación. Se corrigió la documentación de pruebas unitarias (dev.unittest.rst). Se añadió una clase padre o abstract a cada conjunto de tests. Se añadieron servicios al API Client (el archivo dte.py contiene algunos servicios nuevos y probados). Se añadieron comandos en Makefile para los tests.
1 parent a70a44b commit b0f4a5d

38 files changed

Lines changed: 2374 additions & 469 deletions

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ jobs:
3636
LIBREDTE_RUT: ${{ vars.LIBREDTE_RUT }}
3737
run: |
3838
make tests_dte_temp
39+
make tests_cobros
3940
4041
- name: Upload pytest result report
4142
if: failure()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ tests/*.json
2222
tests/*.csv
2323
tests/*.pdf
2424
tests/*.html
25+
tests/archivos/dte_facturacion/*

.scrutinizer.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build:
66
analysis:
77
tests:
88
override:
9-
- php-scrutinizer-run
9+
- python-scrutinizer-run
1010
- command: make tests_dte_temp
1111
coverage:
1212
file: var/tests-coverage.xml

Makefile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,20 @@ install-dev:
1212
tests: install-dev
1313
python tests/run.py
1414

15+
tests_dte:
16+
python3 tests/run.py dte_facturacion
17+
18+
tests_dte_real:
19+
python3 tests/run.py dte_facturacion.dte_real
20+
21+
tests_dte_rec:
22+
python3 tests/run.py dte_facturacion.dte_recibidos
23+
1524
tests_dte_temp:
16-
python3 tests/run.py dte_facturacion.test_generar_dte_temporal
25+
python3 tests/run.py dte_facturacion.dte_temp
26+
27+
tests_cobros:
28+
python3 tests/run.py pagos_cobros_masivos
1729

1830
docs:
1931
sphinx-apidoc -o docs libredte && sphinx-build -b html docs docs/_build/html

docs/dev.unittest.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,18 @@ Para ejecutar todas las pruebas, utilizar el siguiente comando:
2020
2121
python3 tests/run.py
2222
23-
También es posible ejecutar un archivo de pruebas específico, indicando el archivo a utilizar. Ejemplo:
23+
También es posible ejecutar un archivo de pruebas específico, indicando el archivo a utilizar. Ejemplos:
2424

2525
.. code:: shell
2626
27-
python3 tests/run.py dte_facturacion.test_generar_dte_temporal
27+
python3 tests/run.py dte_facturacion.dte_temp.test_emitir_dte_temp
28+
python3 tests/run.py pagos_cobros_masivos.test_buscar_cobro_programado
2829
2930
Además puedes elegir una única prueba específica, utilizando la ruta completa:
3031

3132
.. code:: shell
3233
33-
python3 tests/run.py dte_facturacion.test_buscar_documento_emitido.TestBuscarDocumentoEmitido.test_dte_buscar_documento_emitido
34+
python3 tests/run.py dte_facturacion.test_emitir_dte_temp.TestEmitirDteTemp.test_emitir_dte_temp
3435
3536
.. important::
3637
Para el ejemplo anterior, se necesita tener al menos 1 DTE emitido.

libredte/api_client/__init__.py

Lines changed: 104 additions & 56 deletions
Large diffs are not rendered by default.

libredte/api_client/cobros.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ class Cobros(ApiBase):
2727
como obtener información sobre cobros específicos y realizar pagos de cobros.
2828
"""
2929

30-
def get_cobro(self, emisor, cobro):
30+
def get_cobros(self, emisor, filtros):
3131
"""
32-
Obtiene la información de un cobro específico.
32+
Obtiene la información de varios cobros.
3333
34-
Realiza una solicitud POST para buscar información sobre un cobro dado
35-
el identificador del emisor y los datos del cobro.
34+
Realiza una solicitud POST para buscar información sobre múltiples cobros
35+
dado el identificador del emisor y filtros de los cobros.
3636
37-
:param str emisor: Identificador del emisor del cobro.
38-
:param dict cobro: Datos del cobro a buscar.
37+
:param str emisor: Identificador del emisor de los cobros.
38+
:param dict filtros: Datos de filtrado de cobros.
3939
:return: Respuesta JSON con la información del cobro.
4040
"""
4141
url = "/pagos/cobros/buscar/%(emisor)s" % {'emisor' : emisor}
42-
return self.client.post(url, data=cobro)
42+
return self.client.post(url, data = filtros)
4343

4444
def pagar_cobro(self, codigo, emisor, pagar_cobro):
4545
"""
@@ -58,14 +58,15 @@ def pagar_cobro(self, codigo, emisor, pagar_cobro):
5858
'codigo' : codigo,
5959
'emisor' : emisor
6060
}
61-
return self.client.post(url, data=pagar_cobro)
61+
return self.client.post(url, data = pagar_cobro)
6262

6363
def get_cobro_dte_temporal(self, receptor, dte, codigo, emisor):
6464
"""
6565
Obtiene la información de cobro asociada a un DTE temporal específico.
6666
67-
Realiza una solicitud POST para buscar información de cobro basada en un DTE temporal,
68-
dado el RUT del receptor, el tipo de DTE, el código del DTE temporal, y el RUT del emisor.
67+
Realiza una solicitud POST para buscar información de cobro basada en un
68+
DTE temporal, dado el RUT del receptor, el tipo de DTE, el código del
69+
DTE temporal, y el RUT del emisor.
6970
7071
:param str receptor: RUT del receptor asociado al DTE temporal.
7172
:param str dte: Tipo de DTE temporal.
@@ -85,8 +86,8 @@ def get_cobro_dte_real(self, dte, folio, emisor):
8586
"""
8687
Obtiene la información de cobro asociada a un DTE real específico.
8788
88-
Envia una solicitud POST para buscar información de cobro basada en un DTE real,
89-
dado el tipo de DTE, el folio del DTE, y el RUT del emisor.
89+
Envia una solicitud POST para buscar información de cobro basada en un
90+
DTE real, dado el tipo de DTE, el folio del DTE, y el RUT del emisor.
9091
9192
:param str dte: Tipo de DTE real.
9293
:param str folio: Folio del DTE real.
@@ -104,10 +105,10 @@ def get_cobro_info(self, codigo, emisor):
104105
"""
105106
Obtiene información detallada de un cobro específico.
106107
107-
Realiza una solicitud POST para recuperar detalles completos sobre un cobro,
108-
identificado por su código y el RUT del emisor. Esta información puede incluir
109-
detalles del estado del cobro, montos, fechas relevantes, entre otros datos
110-
específicos del cobro consultado.
108+
Realiza una solicitud POST para recuperar detalles completos sobre un
109+
cobro, identificado por su código y el RUT del emisor. Esta información
110+
puede incluir detalles del estado del cobro, montos, fechas relevantes,
111+
entre otros datos específicos del cobro consultado.
111112
112113
:param str codigo: Código único que identifica el cobro.
113114
:param str emisor: RUT del emisor asociado al cobro.

libredte/api_client/dte.py

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ class Dte(ApiBase):
2323
"""
2424
Clase para interactuar con los endpoints de DTE de la API.
2525
26-
Esta clase hereda de ApiBase y proporciona métodos específicos para operaciones relacionadas con DTE,
27-
como obtener información del receptor, emitir y generar DTEs, tanto temporales como reales, y enviar DTEs por correo electrónico.
26+
Esta clase hereda de ApiBase y proporciona métodos específicos para operaciones
27+
relacionadas con DTE, como obtener información del receptor, emitir y
28+
generar DTEs, tanto temporales como reales, y enviar DTEs por correo electrónico.
2829
"""
2930

30-
def emitir_dte_temporal(self, dte_temporal, filtros=None):
31+
def emitir_dte_temporal(self, dte_temporal, filtros = None):
3132
"""
3233
Emite un DTE temporal.
3334
@@ -37,9 +38,9 @@ def emitir_dte_temporal(self, dte_temporal, filtros=None):
3738
"""
3839
filtros = '' if filtros is None else urlencode(filtros)
3940
url = "/dte/documentos/emitir?%(filtros)s" % {'filtros' : filtros}
40-
return self.client.post(url, data=dte_temporal)
41+
return self.client.post(url, data = dte_temporal)
4142

42-
def get_dte_temporal(self, receptor, dte, codigo, emisor, filtros=None):
43+
def get_dte_temporal(self, receptor, dte, codigo, emisor, filtros = None):
4344
"""
4445
Obtiene información de un DTE temporal específico.
4546
@@ -68,7 +69,8 @@ def delete_dte_temporal(self, receptor, dte, codigo, emisor):
6869
:param str dte: Tipo de DTE.
6970
:param str codigo: Código del DTE temporal.
7071
:param str emisor: RUT del emisor.
71-
:return: Respuesta JSON con un boolean que retorna verdadero si se eliminó el DTE temporal.
72+
:return: Respuesta JSON con un boolean que retorna verdadero si se
73+
eliminó el DTE temporal.
7274
"""
7375
url = "/dte/dte_tmps/eliminar/%(receptor)s/%(dte)s/%(codigo)s/%(emisor)s" % {
7476
'receptor' : receptor,
@@ -78,18 +80,19 @@ def delete_dte_temporal(self, receptor, dte, codigo, emisor):
7880
}
7981
return self.client.get(url)
8082

81-
def emitir_dte_real(self, dte_real, filtros=None):
83+
def emitir_dte_real(self, dte_real, filtros = None):
8284
"""
83-
Genera un DTE real a partir de los datos proporcionados, correspondientes aun dte temporal.
85+
Genera un DTE real a partir de los datos proporcionados, correspondientes
86+
a un dte temporal.
8487
8588
:param dict dte_real: Datos del DTE real a generar.
8689
:return: Respuesta JSON del DTE real generado.
8790
"""
8891
filtros = '' if filtros is None else urlencode(filtros)
8992
url = "/dte/documentos/generar?%(filtros)s" % {'filtros' : filtros}
90-
return self.client.post(url, data=dte_real)
93+
return self.client.post(url, data = dte_real)
9194

92-
def get_dte_real(self, dte, folio, emisor, filtros=None):
95+
def get_dte_real(self, dte, folio, emisor, filtros = None):
9396
"""
9497
Obtiene información de un DTE real específico.
9598
@@ -125,7 +128,7 @@ def dte_temporal_enviar_email(self, receptor, dte, codigo, emisor, data_email):
125128
'codigo' : codigo,
126129
'emisor' : emisor
127130
}
128-
return self.client.post(url, data=data_email)
131+
return self.client.post(url, data = data_email)
129132

130133
def dte_real_enviar_email(self, dte, folio, emisor, data_email):
131134
"""
@@ -142,9 +145,9 @@ def dte_real_enviar_email(self, dte, folio, emisor, data_email):
142145
'folio' : folio,
143146
'emisor' : emisor
144147
}
145-
return self.client.post(url, data=data_email)
148+
return self.client.post(url, data = data_email)
146149

147-
def get_pdf_real(self, dte, folio, emisor, filtros=None):
150+
def get_pdf_dte_real(self, dte, folio, emisor, filtros = None):
148151
"""
149152
Obtiene el PDF de un DTE real específico.
150153
@@ -172,9 +175,9 @@ def get_dte_emitidos(self, emisor, filtros):
172175
:return: Respuesta JSON con los DTEs emitidos que coinciden con los filtros.
173176
"""
174177
url = "/dte/dte_emitidos/buscar/%(emisor)s" % {'emisor' : emisor}
175-
return self.client.post(url, data=filtros)
178+
return self.client.post(url, data = filtros)
176179

177-
def dte_emitidos_actualizar_estado(self, dte, folio, emisor, filtros=None):
180+
def dte_emitidos_actualizar_estado(self, dte, folio, emisor, filtros = None):
178181
"""
179182
Actualiza el estado de un DTE emitido.
180183
@@ -200,9 +203,9 @@ def dte_emitidos_consultar(self, filtros):
200203
:param dict filtros: Filtros de búsqueda para aplicar en la consulta.
201204
:return: Respuesta JSON con los DTEs emitidos que coinciden con los filtros.
202205
"""
203-
return self.client.post('/dte/dte_emitidos/consultar', data=filtros)
206+
return self.client.post('/dte/dte_emitidos/consultar', data = filtros)
204207

205-
def dte_emitidos_ted(self, dte, folio, emisor, filtros=None):
208+
def dte_emitidos_ted(self, dte, folio, emisor, filtros = None):
206209
"""
207210
Obtiene el TED (Timbre Electrónico de DTE) de un DTE emitido.
208211
@@ -221,7 +224,7 @@ def dte_emitidos_ted(self, dte, folio, emisor, filtros=None):
221224
}
222225
return self.client.get(url)
223226

224-
def listar_dtes_temporales(self, emisor, filtros):
227+
def get_dte_temporales(self, emisor, filtros):
225228
"""
226229
Obtiene un listado de DTEs temporales.
227230
@@ -230,34 +233,26 @@ def listar_dtes_temporales(self, emisor, filtros):
230233
:return: Respuesta JSON con la lista del DTEs temporales.
231234
"""
232235
url = "/dte/dte_tmps/buscar/%(emisor)s" % {'emisor' : emisor}
233-
return self.client.post(url, data=filtros)
236+
return self.client.post(url, data = filtros)
234237

235-
def listar_dtes_emitidos(self, emisor, filtros):
236-
"""
237-
Obtiene un listado de DTEs emitidos (reales).
238-
239-
:param str emisor: RUT del emisor.
240-
:param dict filtros: Parámetros adicionales para la consulta (opcional).
241-
:return: Respuesta JSON con la lista del DTEs emitidos.
242-
"""
243-
url = "/dte/dte_emitidos/buscar/%(emisor)s" % {'emisor' : emisor}
244-
return self.client.post(url, data=filtros)
245-
246-
def listar_dtes_recibidos(self, receptor, filtros):
238+
def get_dte_recibidos(self, receptor, filtros):
247239
"""
248240
Obtiene un listado de DTEs recibidos.
249241
250242
:param str receptor: RUT del receptor.
251243
:param dict filtros: Parámetros adicionales para la consulta (opcional).
252244
:return: Respuesta JSON con la lista del DTEs recibidos.
253245
"""
254-
url = "/dte/dte_recibidos/buscar/%(receptor)s" % {'receptor' : receptor}
255-
return self.client.post(url, data=filtros)
246+
url = "/dte/dte_recibidos/buscar/%(receptor)s" % {
247+
'receptor' : receptor
248+
}
249+
return self.client.post(url, data = filtros)
256250

257-
def get_pdf_temporal(self, receptor, dte, codigo, emisor, filtros=None):
251+
def get_pdf_dte_temporal(self, receptor, dte, codigo, emisor, filtros = None):
258252
"""
259-
Obtiene el PDF de un DTE real específico.
253+
Obtiene el PDF de un DTE temporal específico.
260254
255+
:param str receptor: RUT del receptor.
261256
:param str dte: Tipo de DTE.
262257
:param str codigo: Código del DTE.
263258
:param str emisor: RUT del emisor.
@@ -274,6 +269,24 @@ def get_pdf_temporal(self, receptor, dte, codigo, emisor, filtros=None):
274269
}
275270
return self.client.get(url)
276271

272+
def get_xml_dte_temporal(self, receptor, dte, codigo, emisor):
273+
"""
274+
Obtiene un XML de un DTE temporal.
275+
276+
:param str receptor: RUT del receptor.
277+
:param str dte: Tipo de DTE.
278+
:param str codigo: Codigo del DTE emitido.
279+
:param str emisor: RUT del emisor.
280+
:return: Respuesta codificada en base64 con el XML del DTE emitido.
281+
"""
282+
url = "/dte/dte_tmps/xml/%(receptor)s/%(dte)s/%(codigo)s/%(emisor)s" % {
283+
'receptor': receptor,
284+
'dte' : dte,
285+
'codigo' : codigo,
286+
'emisor' : emisor
287+
}
288+
return self.client.get(url)
289+
277290
def get_xml_dte_real(self, dte, folio, emisor):
278291
"""
279292
Obtiene un XML de un DTE emitido.
@@ -308,7 +321,7 @@ def get_xml_dte_recibido(self, emisor, dte, folio, receptor):
308321
}
309322
return self.client.get(url)
310323

311-
def get_dte_recibido(self, emisor, dte, folio, receptor, filtros=None):
324+
def get_dte_recibido(self, emisor, dte, folio, receptor, filtros = None):
312325
"""
313326
Obtiene información de un DTE temporal específico.
314327

libredte/api_client/sistema.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,17 @@ def get_moneda_cambios(self, to, day):
3131
"""
3232
Obtiene la tasa de cambio de moneda de USD a otra moneda en una fecha específica.
3333
34-
Este método realiza una solicitud GET para obtener la tasa de cambio desde USD
35-
hacia la moneda especificada por el usuario para una fecha dada. Es útil para
36-
consultas de conversiones de moneda históricas o actuales.
34+
Este método realiza una solicitud GET para obtener la tasa de cambio desde
35+
USD hacia la moneda especificada por el usuario para una fecha dada. Es
36+
útil para consultas de conversiones de moneda históricas o actuales.
3737
3838
:param str to: Código de la moneda destino a la cual se desea convertir USD.
3939
:param str day: Fecha de la consulta de la tasa de cambio.
40-
:return: Respuesta JSON con la tasa de cambio desde USD a la moneda especificada en la fecha indicada.
40+
:return: Respuesta JSON con la tasa de cambio desde USD a la moneda
41+
especificada en la fecha indicada.
4142
"""
42-
url = "/sistema/general/moneda_cambios/tasa/USD/%(to)s/%(day)s" % {'to' : to, 'day' : day}
43+
url = "/sistema/general/moneda_cambios/tasa/USD/%(to)s/%(day)s" % {
44+
'to' : to,
45+
'day' : day
46+
}
4347
return self.client.get(url)

0 commit comments

Comments
 (0)