diff --git a/src/cl_sii/dte/constants.py b/src/cl_sii/dte/constants.py index 5d57a2d4..c69f1288 100644 --- a/src/cl_sii/dte/constants.py +++ b/src/cl_sii/dte/constants.py @@ -147,14 +147,20 @@ class TipoDte(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/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L58-L60 - # https://github.com/fyntex/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) ? + FACTURA_EXPORTACION_ELECTRONICA = 110 + """Factura de exportación electrónica.""" + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L58 + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L713 + + NOTA_DEBITO_EXPORTACION_ELECTRONICA = 111 + """Nota de débito de exportación electrónica.""" + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L59 + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L714 + + NOTA_CREDITO_EXPORTACION_ELECTRONICA = 112 + """Nota de crédito de exportación electrónica.""" + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L60 + # https://github.com/fyntex/lib-cl-sii-python/blob/f57a326/cl_sii/data/ref/factura_electronica/schemas-xml/SiiTypes_v10.xsd#L715 @property def is_factura(self) -> bool: @@ -166,6 +172,8 @@ def is_factura(self) -> bool: result = True elif self is TipoDte.LIQUIDACION_FACTURA_ELECTRONICA: result = True + elif self is TipoDte.FACTURA_EXPORTACION_ELECTRONICA: + result = True else: result = False @@ -179,6 +187,8 @@ def is_factura_venta(self) -> bool: result = True elif self is TipoDte.LIQUIDACION_FACTURA_ELECTRONICA: result = True + elif self is TipoDte.FACTURA_EXPORTACION_ELECTRONICA: + result = True else: result = False @@ -199,6 +209,10 @@ def is_nota(self) -> bool: result = True elif self is TipoDte.NOTA_CREDITO_ELECTRONICA: result = True + elif self is TipoDte.NOTA_DEBITO_EXPORTACION_ELECTRONICA: + result = True + elif self is TipoDte.NOTA_CREDITO_EXPORTACION_ELECTRONICA: + result = True else: result = False @@ -295,6 +309,9 @@ def receptor_is_vendedor(self) -> bool: TipoDte.NOTA_CREDITO_ELECTRONICA, TipoDte.NOTA_DEBITO_ELECTRONICA, TipoDte.FACTURA_COMPRA_ELECTRONICA, + TipoDte.FACTURA_EXPORTACION_ELECTRONICA, + TipoDte.NOTA_DEBITO_EXPORTACION_ELECTRONICA, + TipoDte.NOTA_CREDITO_EXPORTACION_ELECTRONICA, } ) @@ -345,6 +362,8 @@ def receptor_is_vendedor(self) -> bool: { TipoDte.NOTA_CREDITO_ELECTRONICA, TipoDte.NOTA_DEBITO_ELECTRONICA, + TipoDte.NOTA_DEBITO_EXPORTACION_ELECTRONICA, + TipoDte.NOTA_CREDITO_EXPORTACION_ELECTRONICA, } ) diff --git a/src/tests/test_dte_constants.py b/src/tests/test_dte_constants.py index fc509aeb..019e7a60 100644 --- a/src/tests/test_dte_constants.py +++ b/src/tests/test_dte_constants.py @@ -152,3 +152,57 @@ def test_NOTA_CREDITO_ELECTRONICA(self) -> None: for result, expected in assertions: self.assertTrue(result is expected) + + def test_FACTURA_EXPORTACION_ELECTRONICA(self) -> None: + value = self.TipoDte.FACTURA_EXPORTACION_ELECTRONICA + + self.assertEqual(value.name, 'FACTURA_EXPORTACION_ELECTRONICA') + self.assertEqual(value.value, 110) + + 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.assertTrue(result is expected) + + def test_NOTA_DEBITO_EXPORTACION_ELECTRONICA(self) -> None: + value = self.TipoDte.NOTA_DEBITO_EXPORTACION_ELECTRONICA + + self.assertEqual(value.name, 'NOTA_DEBITO_EXPORTACION_ELECTRONICA') + self.assertEqual(value.value, 111) + + assertions = [ + (value.is_factura, False), + (value.is_factura_venta, False), + (value.is_factura_compra, False), + (value.is_nota, True), + (value.emisor_is_vendedor, False), + (value.receptor_is_vendedor, False), + ] + + for result, expected in assertions: + self.assertTrue(result is expected) + + def test_NOTA_CREDITO_EXPORTACION_ELECTRONICA(self) -> None: + value = self.TipoDte.NOTA_CREDITO_EXPORTACION_ELECTRONICA + + self.assertEqual(value.name, 'NOTA_CREDITO_EXPORTACION_ELECTRONICA') + self.assertEqual(value.value, 112) + + assertions = [ + (value.is_factura, False), + (value.is_factura_venta, False), + (value.is_factura_compra, False), + (value.is_nota, True), + (value.emisor_is_vendedor, False), + (value.receptor_is_vendedor, False), + ] + + for result, expected in assertions: + self.assertTrue(result is expected) diff --git a/src/tests/test_rcv_constants.py b/src/tests/test_rcv_constants.py index 2c3c2e32..f62226cd 100644 --- a/src/tests/test_rcv_constants.py +++ b/src/tests/test_rcv_constants.py @@ -118,6 +118,18 @@ def test_as_tipo_dte(self) -> None: self.RcvTipoDocto.FACTURA_ELECTRONICA.as_tipo_dte(), TipoDte.FACTURA_ELECTRONICA, ) + self.assertEqual( + self.RcvTipoDocto.FACTURA_EXPORTACION_ELECTRONICA.as_tipo_dte(), + TipoDte.FACTURA_EXPORTACION_ELECTRONICA, + ) + self.assertEqual( + self.RcvTipoDocto.NOTA_DEBITO_EXPORTACION_ELECTRONICA.as_tipo_dte(), + TipoDte.NOTA_DEBITO_EXPORTACION_ELECTRONICA, + ) + self.assertEqual( + self.RcvTipoDocto.NOTA_CREDITO_EXPORTACION_ELECTRONICA.as_tipo_dte(), + TipoDte.NOTA_CREDITO_EXPORTACION_ELECTRONICA, + ) with self.assertRaises(ValueError) as cm: self.RcvTipoDocto.FACTURA.as_tipo_dte() diff --git a/src/tests/test_rcv_data_models.py b/src/tests/test_rcv_data_models.py index 8baf510e..2adebd5d 100644 --- a/src/tests/test_rcv_data_models.py +++ b/src/tests/test_rcv_data_models.py @@ -450,6 +450,41 @@ def test_get_documento_referencia_dte_natural_keys(self) -> None: self.assertEqual(expected_doc_ref_dte_natural_key, actual_doc_ref_dte_natural_key) + # Detalle Entry that references an export DTE: + + rv_detalle_entry_with_export_doc_ref = dataclasses.replace( + rv_detalle_entry, + tipo_docto=RcvTipoDocto.FACTURA_EXPORTACION_ELECTRONICA, + folio=2233, + documento_referencias=[ + DocumentoReferencia( + tipo_documento_referencia=RcvTipoDocto.FACTURA_EXPORTACION_ELECTRONICA, + folio_documento_referencia=12345, + ) + ], + ) + self.assertEqual( + cl_sii.dte.data_models.DteNaturalKey( + emisor_rut=Rut('76354771-K'), + tipo_dte=cl_sii.dte.constants.TipoDte.FACTURA_EXPORTACION_ELECTRONICA, + folio=2233, + ), + rv_detalle_entry_with_export_doc_ref.as_dte_data_l2().natural_key, + ) + + expected_doc_ref_dte_natural_key = [ + cl_sii.dte.data_models.DteNaturalKey( + emisor_rut=Rut('76354771-K'), + tipo_dte=cl_sii.dte.constants.TipoDte.FACTURA_EXPORTACION_ELECTRONICA, + folio=12345, + ) + ] + actual_doc_ref_dte_natural_key = ( + rv_detalle_entry_with_export_doc_ref.get_documento_referencia_dte_natural_keys() + ) + + self.assertEqual(expected_doc_ref_dte_natural_key, actual_doc_ref_dte_natural_key) + # Detalle Entry that references a documento that is a valid DTE # but not a valid RCV Tipo de Documento: