Giter Club home page Giter Club logo

lib-cl-sii-python's Introduction

cl-sii Python lib

PyPI Package Version Python Versions License

Python library for Servicio de Impuestos Internos (SII) of Chile.

Documentation

The full documentation is at https://lib-cl-sii-python.readthedocs.io.

Dashboard

Development

VCS Branch Deployment Environment VCS Repository CI/CD Status
develop Staging GitHub GitHub Actions
master Production GitHub GitHub Actions
Code Coverage Code Climate Documentation Project Analysis
Codecov Maintainability Read the Docs Open Source Insights

Hosting

Deployment Environment Python Package Registry
Production PyPI

Supported Python versions

Only Python 3.8, 3.9 and 3.10. Python 3.7 and below will not work because we use some features introduced in Python 3.8.

Quickstart

Install package::

pip install cl-sii

And TODO

Features

  • TODO

Tests

Requirements::

make install-dev

Run test suite for all supported Python versions and run tools for code style analysis, static type check, etc::

make test-all
make lint

Check code coverage of tests::

make test-coverage
make test-coverage-report-console

lib-cl-sii-python's People

Contributors

bmunoz89 avatar dependabot[bot] avatar fpinto-cdd avatar glarrain avatar jtrh avatar jtrobles-cdd avatar svillegas-cdd avatar ycouce-cdd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

lib-cl-sii-python's Issues

(draft) dte: verify signature over element 'SetDTE' in 'EnvioDTE'

(draft) dte.parse: `_set_dte_xml_missing_xmlns` does not support a non-root DTE XML element

The following will trigger an error:

import pathlib
from cl_sii.libs import xml_utils
from cl_sii.dte.parse import _set_dte_xml_missing_xmlns, DTE_XMLNS_MAP

file_path = pathlib.Path('SET_DTE_76408488-8_33_591.xml')
envio_dte_xml_doc = xml_utils.parse_untrusted_xml(file_path.read_bytes())
assert envio_dte_xml_doc.tag == '{http://www.sii.cl/SiiDte}EnvioDTE'

set_dte_em = xml_em.find('sii-dte:SetDTE', namespaces=DTE_XMLNS_MAP)
set_dte_em = envio_dte_xml_doc.find('sii-dte:SetDTE', namespaces=DTE_XMLNS_MAP)

dte_em_list = set_dte_em.findall('sii-dte:DTE', namespaces=DTE_XMLNS_MAP)
dte_em = dte_em_list[0]

_set_dte_xml_missing_xmlns(dte_em)
Exception: ('XML root element tag does not match the expected simple or namespaced name.', 'DTE', '{http://www.sii.cl/SiiDte}DTE', '{http://www.sii.cl/SiiDte}EnvioDTE')

For a file like this one (download this example set_dte_76408488-8_33_591.xml)

<?xml version="1.0" encoding="ISO-8859-1"?>
<EnvioDTE version="1.0" xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd">
<SetDTE ID="IDfc7f3b7ee3af4c078d300fd530656928">
<Caratula version="1.0">...</Caratula>
<DTE version="1.0">
<Documento ID="T33F591">...</Documento>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
</Signature>
</DTE>
</SetDTE>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
</Signature>
</EnvioDTE>

Create package with utilities for developers

There are some utilities such as test factories, sample data, helpers, etc. that are not included in the library package because they are not needed for production deployments. However, they are useful during development, so we should find a way to make them easily accessible to developers.

Ref.: https://github.com/fyntex/fyndata-cl-data/blob/6d3866913c02f8e6e83889135d018ca63b015578/fd_cl_data/apps/sii_cte/tests/cl_sii_factories.py#L14-L44
Ref.: https://github.com/fyntex/fyndata-cl-data/blob/04355dbbcf40e4769b80c475dfb77e51e63ddeab/fd_cl_data/apps/sii_rcv/tests/cl_sii_factories.py#L16-L75
Ref.: https://github.com/fyntex/fyndata-cl-data/blob/6d3866913c02f8e6e83889135d018ca63b015578/fd_cl_data/apps/sii_rtc/tests/cl_sii_api_factories.py#L16-L90

CC: @glarrain

rcv.parse_cv: in parse functions detect invalid value of "razon social"

Sentry Issue: FD-CL-DATA-Z

ValueError: Value must not have leading or trailing whitespace.
  File "cl_sii/rcv/parse_csv.py", line 1136, in _parse_rcv_csv_file
    entry = input_csv_row_schema.to_detalle_entry(deserialized_row_data)
  File "cl_sii/rcv/parse_csv.py", line 1046, in to_detalle_entry
    fecha_recepcion_dt=fecha_recepcion_dt,
  File "<string>", line 11, in __init__
  File "cl_sii/rcv/data_models.py", line 189, in __post_init__
    cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social)
  File "cl_sii/dte/data_models.py", line 70, in validate_contribuyente_razon_social
    raise ValueError("Value must not have leading or trailing whitespace.")

Deserialized data to data model instance conversion failed (probably a programming error).

Create data model for "Cesion"

For a "cesión"'s basic data.

Properties:

  • natural_key
  • alt_natural_key
  • dte_natural_key
  • dte_emisor_rut (analogous to dte.data_models.DteDataL1.vendedor_rut)
  • dte_receptor_rut (analogous to dte.data_models.DteDataL1.comprador_rut)

Module `defusedxml.lxml` is not fully protected and is deprecated

We rely on function defusedxml.lxml.fromstring() for our function libs.xml_utils.parse_untrusted_xml(). What should we use instead?

DEPRECATED Example code for lxml.etree protection
The code has NO protection against decompression bombs.

Source

defusedxml.lxml
DEPRECATED The module is deprecated and will be removed in a future release.

Source

CC @jtrh

Alternatives

Perhaps there are others?

  • defusedxml.ElementTree.fromstring
  • defusedxml.cElementTree.fromstring

Security: Django vulnerabilities found in requirements/extras.txt

CVE-2021-3281
moderate severity
Vulnerable versions: >= 3.0, < 3.1.6
Patched version: 3.1.6
In Django 2.2 before 2.2.18, 3.0 before 3.0.12, and 3.1 before 3.1.6, the django.utils.archive.extract method (used by "startapp --template" and "startproject --template") allows directory traversal via an archive with absolute paths or relative paths with dot segments.


CVE-2020-24583
high severity
Vulnerable versions: >= 3.0, < 3.0.10
Patched version: 3.0.10
An issue was discovered in Django 2.2 before 2.2.16, 3.0 before 3.0.10, and 3.1 before 3.1.1 (when Python 3.7+ is used). FILE_UPLOAD_DIRECTORY_PERMISSIONS mode was not applied to intermediate-level directories created in the process of uploading files. It was also not applied to intermediate-level collected static directories when using the collectstatic management command.


CVE-2020-24584
high severity
Vulnerable versions: >= 3.0, < 3.0.10
Patched version: 3.0.10
An issue was discovered in Django 2.2 before 2.2.16, 3.0 before 3.0.10, and 3.1 before 3.1.1 (when Python 3.7+ is used). The intermediate-level directories of the filesystem cache had the system's standard umask rather than 0o077.

(draft) rut.constants: name of `RUT_DIGITS_MIN_VALUE` is misleading

The value 50000000 is the minimum RUT (digits) for a "Persona Jurídica", not for the whole range of RUT. See https://bakercapital.slack.com/archives/CS9G7SZBL/p1580307661000200

Also:

"un RUT sobre 50.000.000 corresponde a una persona jurídica".
No tenemos una fuente oficial para esa afirmación. Sin embargo la experiencia ha probado eso, y una página del BancoEstado dice lo mismo:
"Persona Jurídica es: “Persona ficticia, capaz de ejercer derechos y contraer obligaciones civiles, y de ser representada judicial y extrajudicialmente”. Además de esto, poseen Rut sobre 50 millones."
https://www.bancoestado.cl/imagenes/_microempresas/servicios/informacion-general.asp

https://docs.google.com/presentation/d/1QjjrBMpEoUQaOJXWSMqg9kDBeIUnb4-MOJP16IcBxo0/edit?disco=AAAAEIwVU4k

https://github.com/fyntex/lib-cl-sii-python/blob/c70feb2d32cd0e5bcb023289e9e3737398d3e9c9/cl_sii/rut/constants.py#L19-L20

(draft) Document what is a "Liquidación-Factura Electrónica" (DTE 43)

More info:


Registro de Liquidaciones y Liquidaciones Factura en IECV (antecesor RCV):

El comisionista o consignatario es el emisor del documento y deberá registrar en su
información electrónica de ventas la liquidación/liquidación factura que emita [...]

El mandante es quien recibe el documento y deberá registrarlo en su información
electrónica de ventas y, si se trata de una liquidación factura deberá registrarlo también en
la información electrónica de compras, por el crédito fiscal asociado a la comisión.

Source: SII Factura Electrónica | Ejemplos y Casos Especiales Registro Documentos en IECV y en Declaraciones Juradas 3327 y 3328

rut.crypto_utils: AttributeError causes 'Certificate has no RUT information' exception

AttributeError: 'RFC822Name' object has no attribute 'type_id'
  File "cl_sii/rut/crypto_utils.py", line 36, in get_subject_rut_from_certificate_pfx
    results = [
  File "cl_sii/rut/crypto_utils.py", line 39, in <listcomp>
    if x.type_id == constants.SII_CERT_TITULAR_RUT_OID

Exception: Certificate has no RUT information
(28 additional frame(s) were not displayed)
...
  File "...", line 212, in ...
    ... = ...
  File "...", line 113, in ...
    ...
  File "...", line 303, in ...
    ... = ...
  File "...", line 325, in ...
    '...': cl_sii.rut.crypto_utils.get_subject_rut_from_certificate_pfx(
  File "cl_sii/rut/crypto_utils.py", line 42, in get_subject_rut_from_certificate_pfx
    raise Exception('Certificate has no RUT information')

The above problem is caused because the code of cl_sii.rut.crypto_utils.get_subject_rut_from_certificate_pfx(), when iterating subject_alt_name_ext.value._general_names, attempts to read the attribute type_id of an object that doesn't have it (<RFC822Name(value='****@****.**')>), and that throws an AttributeError. That could be fixed by replacing if x.type_id == constants.SII_CERT_TITULAR_RUT_OID with if hasattr(x, 'type_id') and x.type_id == constants.SII_CERT_TITULAR_RUT_OID.

I would also improve the handling of the AttributeError exception that wraps results = [...] because it's interpreting any AttributeError as Certificate has no RUT information, which hides the actual cause of the error in cases like the current one.

Content of subject_alt_name_ext:

<Extension(oid=<ObjectIdentifier(oid=2.5.29.17, name=subjectAltName)>, critical=False,
    value=<SubjectAlternativeName(
        <GeneralNames([
            <OtherName(type_id=<ObjectIdentifier(oid=1.3.6.1.4.1.8321.1, name=Unknown OID)>, value=b'\x16\n1*******-8')>,
            <OtherName(type_id=<ObjectIdentifier(oid=1.3.6.1.5.5.7.8.3, name=Unknown OID)>, value=b'0\x...\n1****-8\x...')>,
            <RFC822Name(value='****@****.**')>
        ])>
    )>
)>

Ref: #267
CC: @ycouce-cdd, @yrios-cdd

rcv: RC Entry of factura has blank emisor razón social

Can a RcRegistroDetalleEntry of a (non-electronic) factura (<RcvTipoDocto.FACTURA: 30>) have a blank (empty string) emisor razón social?

Sentry Issue: FD-CL-DATA-13E

ValueError: Value must not be empty.
  File "cl_sii/rcv/parse_csv.py", line 1175, in _parse_rcv_csv_file
    entry = input_csv_row_schema.to_detalle_entry(deserialized_row_data)
  File "cl_sii/rcv/parse_csv.py", line 784, in to_detalle_entry
    detalle_entry = RcRegistroDetalleEntry(
  File "<string>", line 12, in __init__
    from datetime import date, datetime
  File "cl_sii/rcv/data_models.py", line 281, in __post_init__
    cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social)
  File "cl_sii/dte/data_models.py", line 76, in validate_contribuyente_razon_social
    raise ValueError("Value must not be empty.")

Deserialized data to data model instance conversion failed (probably a programming error).

docs: add link to project analysis by Open Source Insights

The Open Source Insights page for each package shows the full dependency graph and updates it every day. The information provided can help you make informed decisions about using, building, and maintaining your software.

With Open Source Insights, you can actually see the dependency graph for a package, then isolate the paths to a particular dependency. Or see whether a vulnerability in a dependency might affect your code. Or compare two versions of a package to see how the dependencies have changed in a new release.

Open Source Insights page for PyPI package cl-sii: https://deps.dev/pypi/cl-sii

rcv: RV Entry of factura exportación has blank receptor razón social

Can a RvDetalleEntry of a (non-electronic) factura de exportación (<RcvTipoDocto.FACTURA_EXPORTACION: 101>) have a blank (empty string) receptor razón social?

Sentry Issue: FD-CL-DATA-13F

ValueError: Value must not be empty.
  File "cl_sii/rcv/parse_csv.py", line 1175, in _parse_rcv_csv_file
    entry = input_csv_row_schema.to_detalle_entry(deserialized_row_data)
  File "cl_sii/rcv/parse_csv.py", line 651, in to_detalle_entry
    detalle_entry = RvDetalleEntry(
  File "<string>", line 13, in __init__
    from typing import Optional
  File "cl_sii/rcv/data_models.py", line 244, in __post_init__
    cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social)
  File "cl_sii/dte/data_models.py", line 76, in validate_contribuyente_razon_social
    raise ValueError("Value must not be empty.")

Deserialized data to data model instance conversion failed (probably a programming error).

Check Rut

Hi, in this library is available any method for check a bussiness information by RUT?

cte: SII Form 29 "datos" object may contain field codes with four digits

Problem 1

The schema validates SII Form 29 codes using a regex that matches strings with three digits. New information has shown that codes with four digits are possible.

Problem 2

If problem 1 is fixed, a new problem occurs: The value of the four-digit code 9906 is a date-formatted string ("22/01/2019"), but the data type specified by the SII in the datos object is number (N), not date (F), which causes an error when the code attempts to convert the string value to an integer: ValueError: invalid literal for int() with base 10: '22/01/2019'.

Example for Problems 1 and 2

{
  "campos": {
    "001": "D***",
    "...": "...",
    "596": "0",
    "9906": "22/01/2019"
  },
  "extras": {
    "ADM8703": "",
    "ADM8721": "",
    "BANCO": "",
    "CALIDADDECLARANTE": "Contribuyente",
    "CARTRIB": "1",
    "CLASE": "Rectificatoria con Giro",
    "CODINT": "59*****52",
    "COD_FORM": "F29",
    "DV_ORIGEN": "5",
    "FECHA_HOY": "17/01/2020",
    "FECHA_INGRESO": "22012019",
    "FOLIO": "67******56",
    "MEDIO_INGRESO": "INTERNET",
    "MEDIO_PAGO": "",
    "MOSTRAR_FOLIO": "1",
    "NOMBRES": "C******* *** C***** D*** Z*****",
    "NOMBRE_FUN": "  ",
    "OPCION": "VC",
    "PERIODO": "201812",
    "RUT_ORIGEN": "10****00",
    "TIPO_MOVIMIENTO": "5",
    "TOKEN": "VFC",
    "USUARIO": "0",
    "cant_anuladas": 1
  },
  "folioF": {
    "COD_9902_1": "67******46"
  },
  "glosa": {
    "001": "APELLIDO PATERNO O RAZÓN SOCIAL",
    "...": "...",
    "596": "RETENCION CAMBIO DE SUJETO",
    "9906": "FECHA PRESENTACION DECL. PRIMITIVA "
  },
  "justif": {
    "001": "I",
    "...": "...",
    "596": "D",
    "9906": "I"
  },
  "linea": {
    "001": "0",
    "...": "...",
    "596": "111",
    "9906": "118"
  },
  "tipos": {
    "001": "C",
    "...": "...",
    "596": "M",
    "9906": "N"
  }
}

Ref: Internal ID: a7de52c9-7bc4-4f53-8d06-8e7e2a36be8f

rtc: Signature verification fails for XMLs that are not in their canonical form

Even though it is assumed that a canonicalization algorithm is applied before performing the digital signature calculations of the XML, even if it is referenced in the SignedInfo element, it does not mean that it was necessarily applied. Unfortunately, the SII does not verify that the XML is in its canonical form, so it is common that several of the AECs accepted by the SII are not normalized (See discussion at #242).
For this reason, the signature verification algorithm will fail in those XMLs that, by canonicalizing them before verifying their signature, the normalization introduces changes that modify the content of the XML, e.g. documents containing empty-element tags

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.