diff --git a/cl_sii/dte/data_models.py b/cl_sii/dte/data_models.py index be44f07a..b93c0775 100644 --- a/cl_sii/dte/data_models.py +++ b/cl_sii/dte/data_models.py @@ -347,12 +347,12 @@ class DteDataL2(DteDataL1): # fields ########################################################################### - emisor_razon_social: str = dc_field() + emisor_razon_social: Optional[str] = dc_field() """ "Razón social" (legal name) of the "emisor" of the DTE. """ - receptor_razon_social: str = dc_field() + receptor_razon_social: Optional[str] = dc_field() """ "Razón social" (legal name) of the "receptor" of the DTE. """ @@ -405,13 +405,15 @@ def __post_init__(self) -> None: """ super().__post_init__() - if not isinstance(self.emisor_razon_social, str): - raise TypeError("Inappropriate type of 'emisor_razon_social'.") - validate_contribuyente_razon_social(self.emisor_razon_social) + if self.emisor_razon_social is not None: + if not isinstance(self.emisor_razon_social, str): + raise TypeError("Inappropriate type of 'emisor_razon_social'.") + validate_contribuyente_razon_social(self.emisor_razon_social) - if not isinstance(self.receptor_razon_social, str): - raise TypeError("Inappropriate type of 'receptor_razon_social'.") - validate_contribuyente_razon_social(self.receptor_razon_social) + if self.receptor_razon_social is not None: + if not isinstance(self.receptor_razon_social, str): + raise TypeError("Inappropriate type of 'receptor_razon_social'.") + validate_contribuyente_razon_social(self.receptor_razon_social) if self.fecha_vencimiento_date is not None: if not isinstance(self.fecha_vencimiento_date, date): diff --git a/cl_sii/rcv/data_models.py b/cl_sii/rcv/data_models.py index 3bf416d4..4c68fc2c 100644 --- a/cl_sii/rcv/data_models.py +++ b/cl_sii/rcv/data_models.py @@ -224,7 +224,7 @@ class RvDetalleEntry(RcvDetalleEntry): RCV_KIND = RcvKind.VENTAS RC_ESTADO_CONTABLE = None - emisor_razon_social: str = dc_field() + emisor_razon_social: Optional[str] = dc_field() """ "Razón social" (legal name) of the "emisor" of the "documento". """ @@ -244,9 +244,10 @@ class RvDetalleEntry(RcvDetalleEntry): def __post_init__(self) -> None: super().__post_init__() - if not isinstance(self.emisor_razon_social, str): - raise TypeError("Inappropriate type of 'emisor_razon_social'.") - cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social) + if self.emisor_razon_social is not None: + if not isinstance(self.emisor_razon_social, str): + raise TypeError("Inappropriate type of 'emisor_razon_social'.") + cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social) if not isinstance(self.receptor_razon_social, str): raise TypeError("Inappropriate type of 'receptor_razon_social'.") @@ -280,7 +281,7 @@ class RcRegistroDetalleEntry(RcvDetalleEntry): # TODO: docstring # TODO: can it be None? What happens for those "tipo docto" that do not have a receptor? - receptor_razon_social: str = dc_field() + receptor_razon_social: Optional[str] = dc_field() # TODO: docstring # note: must be timezone-aware. @@ -293,9 +294,10 @@ def __post_init__(self) -> None: raise TypeError("Inappropriate type of 'emisor_razon_social'.") cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social) - if not isinstance(self.receptor_razon_social, str): - raise TypeError("Inappropriate type of 'receptor_razon_social'.") - cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) + if self.receptor_razon_social is not None: + if not isinstance(self.receptor_razon_social, str): + raise TypeError("Inappropriate type of 'receptor_razon_social'.") + cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) if self.fecha_acuse_dt is not None: if not isinstance(self.fecha_acuse_dt, datetime): @@ -331,7 +333,7 @@ class RcReclamadoDetalleEntry(RcvDetalleEntry): # TODO: docstring # TODO: can it be None? What happens for those "tipo docto" that do not have a receptor? - receptor_razon_social: str = dc_field() + receptor_razon_social: Optional[str] = dc_field() # TODO: docstring # note: must be timezone-aware. @@ -344,9 +346,10 @@ def __post_init__(self) -> None: raise TypeError("Inappropriate type of 'emisor_razon_social'.") cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social) - if not isinstance(self.receptor_razon_social, str): - raise TypeError("Inappropriate type of 'receptor_razon_social'.") - cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) + if self.receptor_razon_social is not None: + if not isinstance(self.receptor_razon_social, str): + raise TypeError("Inappropriate type of 'receptor_razon_social'.") + cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) if self.fecha_reclamo_dt is not None: if not isinstance(self.fecha_reclamo_dt, datetime): @@ -371,7 +374,7 @@ class RcPendienteDetalleEntry(RcvDetalleEntry): # TODO: docstring # TODO: can it be None? What happens for those "tipo docto" that do not have a receptor? - receptor_razon_social: str = dc_field() + receptor_razon_social: Optional[str] = dc_field() def __post_init__(self) -> None: super().__post_init__() @@ -380,6 +383,7 @@ def __post_init__(self) -> None: raise TypeError("Inappropriate type of 'emisor_razon_social'.") cl_sii.dte.data_models.validate_contribuyente_razon_social(self.emisor_razon_social) - if not isinstance(self.receptor_razon_social, str): - raise TypeError("Inappropriate type of 'receptor_razon_social'.") - cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) + if self.receptor_razon_social is not None: + if not isinstance(self.receptor_razon_social, str): + raise TypeError("Inappropriate type of 'receptor_razon_social'.") + cl_sii.dte.data_models.validate_contribuyente_razon_social(self.receptor_razon_social) diff --git a/tests/test_dte_data_models.py b/tests/test_dte_data_models.py index 2af47153..c79702bd 100644 --- a/tests/test_dte_data_models.py +++ b/tests/test_dte_data_models.py @@ -238,19 +238,12 @@ def test_init_fail_razon_social_empty(self) -> None: ) self.assertEqual(cm.exception.args, ("Value must not be empty.", )) - def test_init_fail_razon_social_none(self) -> None: - with self.assertRaises(TypeError) as cm: - dataclasses.replace( - self.dte_l2_1, - emisor_razon_social=None, - ) - self.assertEqual(cm.exception.args, ("Inappropriate type of 'emisor_razon_social'.", )) - with self.assertRaises(TypeError) as cm: - dataclasses.replace( - self.dte_l2_1, - receptor_razon_social=None, - ) - self.assertEqual(cm.exception.args, ("Inappropriate type of 'receptor_razon_social'.", )) + def test_init_ok_razon_social_none(self) -> None: + _ = dataclasses.replace( + self.dte_l2_1, + emisor_razon_social=None, + receptor_razon_social=None, + ) def test_init_fail_regression_signature_value_bytes_with_x20(self) -> None: bytes_value_with_x20_as_base64 = 'IN2pkDBxqDnGl4Pfvboi'