Skip to content

Commit

Permalink
Merge pull request #77 from fyndata/develop
Browse files Browse the repository at this point in the history
Release v0.7.4
  • Loading branch information
glarrain committed Aug 8, 2019
2 parents 29ed7f3 + dd4110f commit 7e1c4b5
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.7.3
current_version = 0.7.4
commit = True
tag = True

Expand Down
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
History
-------

0.7.4 (2019-08-08)
+++++++++++++++++++++++

* (PR #76, 2019-08-01) dte: misc data models and enum improvements

0.7.3 (2019-07-09)
+++++++++++++++++++++++

Expand Down
2 changes: 1 addition & 1 deletion cl_sii/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"""


__version__ = '0.7.3'
__version__ = '0.7.4'
43 changes: 41 additions & 2 deletions cl_sii/dte/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,19 @@ class TipoDteEnum(enum.IntEnum):
"""
Enum of "Tipo de DTE".
Source: XML type ``DTEType`` (enum) in official schema ``SiiTypes_v10.xsd``.
https://github.com/fyndata/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L63-L99
Source: from official schema ``SiiTypes_v10.xsd``, the XML types (enums)
``DOCType``, ``DocType``, ``DTEType`` and ``DTEFacturasType`` which are
VERY similar.
https://github.com/fyndata/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd
Notes:
* Enums ``DocType`` and ``DTEType`` have exactly the same elements
(although descriptions differ).
* The elements of the following enums are strictly subgroups of enum ``DOCType``:
* ``DocType`` and ``DTEType``: same elements.
* ``DTEFacturasType``
* ``LIQType``: "Tipos de Liquidaciones".
* ``EXPType``: "Tipos de Facturas de Exportacion".
"""

Expand All @@ -87,6 +98,21 @@ class TipoDteEnum(enum.IntEnum):
# aka 'Factura no Afecta o Exenta Electrónica'
# aka 'Factura Electrónica de Venta de Bienes y Servicios No afectos o Exento de IVA'

LIQUIDACION_FACTURA_ELECTRONICA = 43
"""Liquidación-Factura Electrónica."""
# For more info about a "liquidación-factura [electrónica]" see:
# - SII / FAQ / "¿Qué son las Liquidaciones-Factura?"
# http://www.sii.cl/preguntas_frecuentes/catastro/001_012_0247.htm
# - SII / FAQ / "¿Para qué se utiliza la Liquidación Factura Electrónica?"
# http://www.sii.cl/preguntas_frecuentes/catastro/001_012_3689.htm
# - SII / FAQ / "¿Qué documentos tributarios deben emitir las partes involucradas en un
# contrato de consignación?"
# http://www.sii.cl/preguntas_frecuentes/catastro/001_012_2619.htm
# - SII / resoluciones / "Resolución Exenta SII N°108 del 24 de Octubre del 2005.
# Establece normas y procedimientos de operación referente a la emisión de
# liquidaciones-facturas electrónicas"
# http://www.sii.cl/documentos/resoluciones/2005/reso108.htm

FACTURA_COMPRA_ELECTRONICA = 46
"""Factura electrónica de compra."""
# aka 'Factura de Compra Electrónica'
Expand All @@ -104,6 +130,15 @@ class TipoDteEnum(enum.IntEnum):
"""Nota electrónica de crédito."""
# aka 'Nota de Crédito Electrónica'

# TODO: add
# 110 Factura de exportación electrónica
# 111 Nota de débito de exportación electrónica
# 112 Nota de crédito de exportación electrónica
# https://github.com/fyndata/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L58-L60
# https://github.com/fyndata/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L708-L717
# See 'cl_sii.rcv.constants.RcvTipoDocto'
# Should 'is_factura' be true for a "Factura de exportación electrónica" (110) ?

@property
def is_factura(self) -> bool:
if self is TipoDteEnum.FACTURA_ELECTRONICA:
Expand All @@ -112,6 +147,8 @@ def is_factura(self) -> bool:
result = True
elif self is TipoDteEnum.FACTURA_COMPRA_ELECTRONICA:
result = True
elif self is TipoDteEnum.LIQUIDACION_FACTURA_ELECTRONICA:
result = True
else:
result = False

Expand All @@ -123,6 +160,8 @@ def is_factura_venta(self) -> bool:
result = True
elif self is TipoDteEnum.FACTURA_NO_AFECTA_O_EXENTA_ELECTRONICA:
result = True
elif self is TipoDteEnum.LIQUIDACION_FACTURA_ELECTRONICA:
result = True
else:
result = False

Expand Down
22 changes: 18 additions & 4 deletions cl_sii/dte/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,14 @@ def __post_init__(self) -> None:

validate_dte_monto_total(self.monto_total)

###########################################################################
# properties
###########################################################################

@property
def vendedor_rut(self) -> Rut:
"""
Return the RUT of the "vendedor".
Return the RUT of the "vendedor" aka "proveedor" (supplier).
:raises ValueError:
"""
Expand All @@ -284,9 +288,9 @@ def vendedor_rut(self) -> Rut:
return result

@property
def deudor_rut(self) -> Rut:
def comprador_rut(self) -> Rut:
"""
Return the RUT of the "deudor".
Return the RUT of the "comprador" aka "cliente" (buyer).
:raises ValueError:
"""
Expand All @@ -296,10 +300,20 @@ def deudor_rut(self) -> Rut:
result = self.emisor_rut
else:
raise ValueError(
"Concept \"deudor\" does not apply for this 'tipo_dte'.", self.tipo_dte)
"Concepts \"comprador\" and \"deudor\" do not apply for this 'tipo_dte'.",
self.tipo_dte)

return result

@property
def deudor_rut(self) -> Rut:
"""
Return the RUT of the "deudor" (same as the "comprador").
:raises ValueError:
"""
return self.comprador_rut


@dataclasses.dataclass(frozen=True)
class DteDataL2(DteDataL1):
Expand Down
5 changes: 2 additions & 3 deletions cl_sii/rcv/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ class RcvTipoDocto(enum.IntEnum):
# "liquidación-factura"
###########################################################################

# For more info about a "liquidación-factura" see:
# http://www.sii.cl/preguntas_frecuentes/catastro/001_012_0247.htm
# http://www.sii.cl/preguntas_frecuentes/catastro/001_012_3689.htm
# For more info about a "liquidación-factura" see
# 'cl_sii.dte.constants.TipoDteEnum'.

LIQUIDACION_FACTURA = 40
"""Liquidación-Factura."""
Expand Down
19 changes: 19 additions & 0 deletions tests/test_dte_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_members(self):
{
TipoDteEnum.FACTURA_ELECTRONICA,
TipoDteEnum.FACTURA_NO_AFECTA_O_EXENTA_ELECTRONICA,
TipoDteEnum.LIQUIDACION_FACTURA_ELECTRONICA,
TipoDteEnum.FACTURA_COMPRA_ELECTRONICA,
TipoDteEnum.GUIA_DESPACHO_ELECTRONICA,
TipoDteEnum.NOTA_DEBITO_ELECTRONICA,
Expand Down Expand Up @@ -55,6 +56,24 @@ def test_FACTURA_NO_AFECTA_O_EXENTA_ELECTRONICA(self):
for (result, expected) in assertions:
self.assertTrue(result is expected)

def test_LIQUIDACION_FACTURA_ELECTRONICA(self):
value = TipoDteEnum.LIQUIDACION_FACTURA_ELECTRONICA

self.assertEqual(value.name, 'LIQUIDACION_FACTURA_ELECTRONICA')
self.assertEqual(value.value, 43)

assertions = [
(value.is_factura, True),
(value.is_factura_venta, True),
(value.is_factura_compra, False),
(value.is_nota, False),
(value.emisor_is_vendedor, True),
(value.receptor_is_vendedor, False),
]

for (result, expected) in assertions:
self.assertEqual(result, expected)

def test_FACTURA_COMPRA_ELECTRONICA(self):
value = TipoDteEnum.FACTURA_COMPRA_ELECTRONICA

Expand Down
18 changes: 16 additions & 2 deletions tests/test_dte_data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_as_dict(self) -> None:
monto_total=2996301,
))

def test_vendedor_rut_deudor_rut(self) -> None:
def test_vendedor_rut_comprador_rut(self) -> None:
emisor_rut = self.dte_l1_1.emisor_rut
receptor_rut = self.dte_l1_1.receptor_rut
dte_factura_venta = dataclasses.replace(
Expand All @@ -121,6 +121,7 @@ def test_vendedor_rut_deudor_rut(self) -> None:
dte_nota_credito = dataclasses.replace(
self.dte_l1_1, tipo_dte=TipoDteEnum.NOTA_CREDITO_ELECTRONICA)

# 'vendedor_rut'
self.assertEqual(dte_factura_venta.vendedor_rut, emisor_rut)
self.assertEqual(dte_factura_venta_exenta.vendedor_rut, emisor_rut)
self.assertEqual(dte_factura_compra.vendedor_rut, receptor_rut)
Expand All @@ -130,14 +131,27 @@ def test_vendedor_rut_deudor_rut(self) -> None:
cm.exception.args,
("Concept \"vendedor\" does not apply for this 'tipo_dte'.", dte_nota_credito.tipo_dte))

# 'comprador_rut'
self.assertEqual(dte_factura_venta.comprador_rut, receptor_rut)
self.assertEqual(dte_factura_venta_exenta.comprador_rut, receptor_rut)
self.assertEqual(dte_factura_compra.comprador_rut, emisor_rut)
with self.assertRaises(ValueError) as cm:
self.assertIsNone(dte_nota_credito.comprador_rut)
self.assertEqual(
cm.exception.args,
("Concepts \"comprador\" and \"deudor\" do not apply for this 'tipo_dte'.",
dte_nota_credito.tipo_dte))

# 'deudor_rut'
self.assertEqual(dte_factura_venta.deudor_rut, receptor_rut)
self.assertEqual(dte_factura_venta_exenta.deudor_rut, receptor_rut)
self.assertEqual(dte_factura_compra.deudor_rut, emisor_rut)
with self.assertRaises(ValueError) as cm:
self.assertIsNone(dte_nota_credito.deudor_rut)
self.assertEqual(
cm.exception.args,
("Concept \"deudor\" does not apply for this 'tipo_dte'.", dte_nota_credito.tipo_dte))
("Concepts \"comprador\" and \"deudor\" do not apply for this 'tipo_dte'.",
dte_nota_credito.tipo_dte))


class DteDataL2Test(unittest.TestCase):
Expand Down

0 comments on commit 7e1c4b5

Please sign in to comment.