diff --git a/ejemplos/.coveragerc b/ejemplos/.coveragerc new file mode 100644 index 000000000..a4cc90219 --- /dev/null +++ b/ejemplos/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = . +include = *.py,*.vbs \ No newline at end of file diff --git a/ejemplos/factura_electronica_wrapper.py b/ejemplos/factura_electronica_wrapper.py new file mode 100644 index 000000000..e02c14d4d --- /dev/null +++ b/ejemplos/factura_electronica_wrapper.py @@ -0,0 +1,29 @@ +from pyafipws.wsaa import WSAA +from pyafipws.wsfev1 import WSFEv1 + + +class FacturaElectronicaWrapper: + def __init__(self): + self.wsaa = WSAA() + self.wsfev1 = WSFEv1() + + def autenticar(self, cert, privatekey, wsdl): + return self.wsaa.Autenticar("wsfe", cert, privatekey, wsdl) + + def conectar(self, wsdl, proxy="", wrapper="", cacert=""): + return self.wsfev1.Conectar(wsdl, proxy, wrapper, cacert) + + def crear_factura(self, **kwargs): + return self.wsfev1.CrearFactura(**kwargs) + + def agregar_tributo(self, id, desc, base_imp, alic, importe): + return self.wsfev1.AgregarTributo(id, desc, base_imp, alic, importe) + + def agregar_iva(self, id, base_imp, importe): + return self.wsfev1.AgregarIva(id, base_imp, importe) + + def solicitar_cae(self): + return self.wsfev1.CAESolicitar() + + def comp_ultimo_autorizado(self, tipo_cbte, punto_vta): + return self.wsfev1.CompUltimoAutorizado(tipo_cbte, punto_vta) diff --git a/ejemplos/pyi25/pyi25_wrapper.py b/ejemplos/pyi25/pyi25_wrapper.py new file mode 100644 index 000000000..533e73d2f --- /dev/null +++ b/ejemplos/pyi25/pyi25_wrapper.py @@ -0,0 +1,15 @@ +from pyi25 import PyI25 + + +class PyI25Wrapper: + def __init__(self): + self.pyi25 = PyI25() + + def Version(self): + return self.pyi25.Version + + def DigitoVerificadorModulo10(self, barras): + return self.pyi25.DigitoVerificadorModulo10(barras) + + def GenerarImagen(self, barras, archivo, **kwargs): + return self.pyi25.GenerarImagen(barras, archivo, **kwargs) diff --git a/ejemplos/pyqr/pyqr_wrapper.py b/ejemplos/pyqr/pyqr_wrapper.py new file mode 100644 index 000000000..aa598d96b --- /dev/null +++ b/ejemplos/pyqr/pyqr_wrapper.py @@ -0,0 +1,41 @@ +from pyqr import PyQR + + +class PyQRWrapper: + def __init__(self): + self.pyqr = PyQR() + + def CrearArchivo(self): + return self.pyqr.CrearArchivo() + + def GenerarImagen( + self, + ver, + fecha, + cuit, + pto_vta, + tipo_cmp, + nro_cmp, + importe, + moneda, + ctz, + tipo_doc_rec, + nro_doc_rec, + tipo_cod_aut, + cod_aut, + ): + return self.pyqr.GenerarImagen( + ver, + fecha, + cuit, + pto_vta, + tipo_cmp, + nro_cmp, + importe, + moneda, + ctz, + tipo_doc_rec, + nro_doc_rec, + tipo_cod_aut, + cod_aut, + ) diff --git a/ejemplos/remito_electronico_carnico_wrapper.py b/ejemplos/remito_electronico_carnico_wrapper.py new file mode 100644 index 000000000..483d0d261 --- /dev/null +++ b/ejemplos/remito_electronico_carnico_wrapper.py @@ -0,0 +1,36 @@ +from pyafipws.wsaa import WSAA +from pyafipws.wsremcarne import WSRemCarne + + +class RemitoElectronicoCarnicoWrapper: + def __init__(self): + self.wsaa = WSAA() + self.wsremcarne = WSRemCarne() + + def autenticar(self, cert, privatekey, wsdl): + return self.wsaa.Autenticar("wsremcarne", cert, privatekey, wsdl) + + def conectar(self, wsdl, proxy="", wrapper="", cacert=""): + return self.wsremcarne.Conectar(wsdl, proxy, wrapper, cacert) + + def crear_remito(self, **kwargs): + return self.wsremcarne.CrearRemito(**kwargs) + + def agregar_viaje(self, **kwargs): + return self.wsremcarne.AgregarViaje(**kwargs) + + def agregar_vehiculo(self, dominio_vehiculo, dominio_acoplado): + return self.wsremcarne.AgregarVehiculo( + dominio_vehiculo, dominio_acoplado + ) + + def agregar_mercaderia(self, **kwargs): + return self.wsremcarne.AgregarMercaderia(**kwargs) + + def generar_remito(self, id_cliente, archivo): + return self.wsremcarne.GenerarRemito(id_cliente, archivo) + + def consultar_ultimo_remito_emitido(self, tipo_comprobante, punto_emision): + return self.wsremcarne.ConsultarUltimoRemitoEmitido( + tipo_comprobante, punto_emision + ) diff --git a/tests/init.py b/tests/init.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_vbs_factura_electronica.py b/tests/test_vbs_factura_electronica.py new file mode 100644 index 000000000..e74b62f5d --- /dev/null +++ b/tests/test_vbs_factura_electronica.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +# -*- coding: utf8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Test para factura electronica.vbs""" + + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010-2019 Mariano Reingart" +__license__ = "GPL 3.0" + + +""" +Tests for the FacturaElectronicaWrapper class, +which provides a wrapper around the AFIP web services for electronic invoicing. +The tests cover the following functionality: +- Authenticating with the WSAA web service +- Connecting to the WSFEV1 web service +- Creating a new invoice +- Adding a tax to the invoice +- Adding IVA (VAT) to the invoice +- Requesting a CAE (Electronic Authorization Code) for the invoice +- Retrieving the last authorized invoice number +These tests use the `monkeypatch` fixture to mock the behavior of the web +service calls, allowing the tests to run without actually making +the web service calls. +""" + +import pytest +import sys +import os + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from ejemplos.factura_electronica_wrapper import FacturaElectronicaWrapper + + +@pytest.fixture +def factura_electronica(): + return FacturaElectronicaWrapper() + + +@pytest.mark.dontusefix +def test_autenticar(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsaa, + "Autenticar", + lambda *args: True + ) + assert factura_electronica.autenticar( + "cert.crt", + "key.key", + "https://wsaahomo.afip.gov.ar/ws/services/LoginCms" + ) + + +@pytest.mark.dontusefix +def test_conectar(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsfev1, "Conectar", + lambda *args: True + ) + assert factura_electronica.conectar( + "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL" + ) + + +@pytest.mark.dontusefix +def test_crear_factura(factura_electronica): + factura_data = { + "concepto": 1, + "tipo_doc": 80, + "nro_doc": "33693450239", + "tipo_cbte": 1, + "punto_vta": 4002, + "cbt_desde": 1, + "cbt_hasta": 1, + "imp_total": "124.00", + "imp_tot_conc": "2.00", + "imp_neto": "100.00", + "imp_iva": "21.00", + "imp_trib": "1.00", + "imp_op_ex": "0.00", + "fecha_cbte": "20230101", + "moneda_id": "PES", + "moneda_ctz": "1.000", + } + assert factura_electronica.crear_factura(**factura_data) + + +@pytest.mark.dontusefix +def test_agregar_tributo(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsfev1, "AgregarTributo", lambda *args: True + ) + assert factura_electronica.agregar_tributo( + 99, "Impuesto Municipal Matanza", "100.00", "1.00", "1.00" + ) + + +@pytest.mark.dontusefix +def test_agregar_iva(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsfev1, "AgregarIva", + lambda *args: True + ) + assert factura_electronica.agregar_iva(5, "100.00", "21.00") + + +@pytest.mark.dontusefix +def test_solicitar_cae(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsfev1, "CAESolicitar", + lambda: "12345678" + ) + assert factura_electronica.solicitar_cae() == "12345678" + + +@pytest.mark.dontusefix +def test_comp_ultimo_autorizado(monkeypatch, factura_electronica): + monkeypatch.setattr( + factura_electronica.wsfev1, "CompUltimoAutorizado", lambda *args: 1234 + ) + assert factura_electronica.comp_ultimo_autorizado(1, 4002) == 1234 + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) \ No newline at end of file diff --git a/tests/test_vbs_pyi25.py b/tests/test_vbs_pyi25.py new file mode 100644 index 000000000..06c996c9b --- /dev/null +++ b/tests/test_vbs_pyi25.py @@ -0,0 +1,71 @@ +#!/usr/bin/python +# -*- coding: utf8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Test para pyi25.vbs""" + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010-2019 Mariano Reingart" +__license__ = "GPL 3.0" + + +""" +This module contains tests for the PyI25Wrapper class, +which is a wrapper around a library for generating barcodes +in the Interleaved 2 of 5 (I25) format. +The tests cover the following functionality: +- Retrieving the version information of the PyI25Wrapper +- Generating a barcode string with a valid check digit +- Generating a barcode image file from a barcode string +The tests use the pytest framework and include fixtures +and markers to manage the test setup and execution. +""" +import pytest +import os +import sys + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from ejemplos.pyi25.pyi25_wrapper import PyI25Wrapper + + +@pytest.fixture(scope="module") +def pyi25(): + return PyI25Wrapper() + + +@pytest.mark.dontusefix +def test_pyi25_version(pyi25): + version = pyi25.Version() + assert version, "Version information not found" + print(f"Version: {version}") + + +@pytest.mark.dontusefix +def test_pyi25_barcode_generation(pyi25): + barras = "202675653930240016120303473904220110529" + barras_with_verifier = barras + pyi25.DigitoVerificadorModulo10(barras) + assert ( + len(barras_with_verifier) == 40 + ), f"Barcode length is {len(barras_with_verifier)}, expected 40" + print(f"Barras: {barras_with_verifier}") + + +@pytest.mark.dontusefix +def test_pyi25_image_generation(pyi25): + barras = "202675653930240016120303473904220110529" + barras_with_verifier = barras + pyi25.DigitoVerificadorModulo10(barras) + output_file = "test_barcode.png" + pyi25.GenerarImagen(barras_with_verifier, output_file) + assert os.path.exists( + output_file + ), f"Generated image file not found at {output_file}" + print(f"Listo! {output_file}") \ No newline at end of file diff --git a/tests/test_vbs_pyqr.py b/tests/test_vbs_pyqr.py new file mode 100644 index 000000000..4868410d1 --- /dev/null +++ b/tests/test_vbs_pyqr.py @@ -0,0 +1,95 @@ +#!/usr/bin/python +# -*- coding: utf8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Test para pyqr.vbs""" + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010-2019 Mariano Reingart" +__license__ = "GPL 3.0" + + +""" +This module contains tests for the PyQRWrapper class, +which is used to generate QR codes for Argentine electronic invoices. +The tests cover the following functionality: +- `test_pyqr_crear_archivo`: Verifies that the `CrearArchivo` method +returns a non-empty value. +- `test_pyqr_generar_imagen`: Verifies that the `GenerarImagen` method +returns a valid URL for the generated QR code image. +""" + + +import pytest +import sys +import os +from urllib.parse import urlparse + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from ejemplos.pyqr.pyqr_wrapper import PyQRWrapper + + +@pytest.fixture(scope="module") +def pyqr(): + return PyQRWrapper() + + +@pytest.mark.dontusefix +def test_pyqr_crear_archivo(pyqr): + archivo = pyqr.CrearArchivo() + assert archivo, "CrearArchivo should return a non-empty value" + print(f"Archivo: {archivo}") + + +@pytest.mark.dontusefix +def test_pyqr_generar_imagen(pyqr): + ver = 1 + fecha = "2020-10-13" + cuit = 30000000007 + pto_vta = 10 + tipo_cmp = 1 + nro_cmp = 94 + importe = 12100 + moneda = "DOL" + ctz = 65 + tipo_doc_rec = 80 + nro_doc_rec = 20000000001 + tipo_cod_aut = "E" + cod_aut = 70417054367476 + + url = pyqr.GenerarImagen( + ver, + fecha, + cuit, + pto_vta, + tipo_cmp, + nro_cmp, + importe, + moneda, + ctz, + tipo_doc_rec, + nro_doc_rec, + tipo_cod_aut, + cod_aut, + ) + + assert url, "GenerarImagen should return a non-empty URL" + parsed_url = urlparse(url) + assert parsed_url.scheme and parsed_url.netloc, f"Invalid URL format: {url}" + assert parsed_url.path.endswith( + "/qr/" + ), f"URL does not end with expected path: {url}" + print(f"URL: {url}") + + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) \ No newline at end of file diff --git a/tests/test_vbs_remito_electronico_carnico.py b/tests/test_vbs_remito_electronico_carnico.py new file mode 100644 index 000000000..0aad2c829 --- /dev/null +++ b/tests/test_vbs_remito_electronico_carnico.py @@ -0,0 +1,115 @@ +#!/usr/bin/python +# -*- coding: utf8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Test para remito electronico carnico.vbs""" + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010-2019 Mariano Reingart" +__license__ = "GPL 3.0" + + +""" +This module contains tests for the RemitoElectronicoCarnicoWrapper class, which is used to interact with the AFIP's Remito Electrónico Cárnico web service. +The tests cover the following functionality: +- Authenticating with the WSAA service +- Connecting to the WSREMCARNE service +- Creating a new remito (electronic shipping document) +- Adding a trip to the remito +- Adding a vehicle to the remito +- Adding merchandise to the remito +- Generating the remito +- Retrieving the last generated remito number +Each test uses the `monkeypatch` fixture to mock the behavior of the underlying WSAA and WSREMCARNE services, allowing the tests to run without actually making external service calls. +""" + +import pytest +import sys +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from ejemplos.remito_electronico_carnico_wrapper import RemitoElectronicoCarnicoWrapper + +@pytest.fixture +def remito_electronico(): + return RemitoElectronicoCarnicoWrapper() + +@pytest.mark.dontusefix +def test_autenticar(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsaa, 'Autenticar', lambda *args: True) + assert remito_electronico.autenticar("cert.crt", "key.key", "https://wsaahomo.afip.gov.ar/ws/services/LoginCms") + +@pytest.mark.dontusefix +def test_conectar(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'Conectar', lambda *args: True) + assert remito_electronico.conectar("https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL") + +@pytest.mark.dontusefix +def test_crear_remito(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'CrearRemito', lambda **kwargs: True) + remito_data = { + 'tipo_comprobante': 995, + 'punto_emision': 1, + 'tipo_movimiento': "ENV", + 'categoria_emisor': 1, + 'cuit_titular_mercaderia': "20222222223", + 'cod_dom_origen': 1, + 'tipo_receptor': "EM", + 'caracter_receptor': 1, + 'cuit_receptor': "20111111112", + 'cuit_depositario': None, + 'cod_dom_destino': 1, + 'cod_rem_redestinar': None, + 'cod_remito': None, + 'estado': None + } + assert remito_electronico.crear_remito(**remito_data) + +@pytest.mark.dontusefix +def test_agregar_viaje(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'AgregarViaje', lambda **kwargs: True) + viaje_data = { + 'cuit_transportista': "20333333334", + 'cuit_conductor': "20333333334", + 'fecha_inicio_viaje': "2023-01-01", + 'distancia_km': 999 + } + assert remito_electronico.agregar_viaje(**viaje_data) + +@pytest.mark.dontusefix +def test_agregar_vehiculo(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'AgregarVehiculo', lambda *args: True) + assert remito_electronico.agregar_vehiculo("AAA000", "ZZZ000") + +@pytest.mark.dontusefix +def test_agregar_mercaderia(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'AgregarMercaderia', lambda **kwargs: True) + mercaderia_data = { + 'orden': 1, + 'tropa': 1, + 'cod_tipo_prod': "2.13", + 'cantidad': 10, + 'unidades': 1 + } + assert remito_electronico.agregar_mercaderia(**mercaderia_data) + +@pytest.mark.dontusefix +def test_generar_remito(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'GenerarRemito', lambda *args: True) + assert remito_electronico.generar_remito(12345, "qr.png") + +@pytest.mark.dontusefix +def test_consultar_ultimo_remito_emitido(monkeypatch, remito_electronico): + monkeypatch.setattr(remito_electronico.wsremcarne, 'ConsultarUltimoRemitoEmitido', lambda *args: 1234) + assert remito_electronico.consultar_ultimo_remito_emitido(995, 1) == 1234 + +if __name__ == "__main__": + pytest.main([__file__, "-v"]) \ No newline at end of file